Your first Gravv integration

Integrating Gravv begins with creating a customer, then verifying the customer. Once the customer is verified, you can create an account for them. The customer can then fund their account and initiate a transfer to another account, which settles within minutes.

In this tutorial, you will create two customers and open an account for each of them. You will then fund one of the accounts, titled source account, and transfer the funds to the other account, titled destination account.

Prerequisites

To complete this tutorial, you will need the following:

  • your Api Key for every request.

If you haven't obtained it yet, follow the steps in Obtain your API Key.

  • basic understanding of REST APIs and cURL
  • a document to save response details
  • ability to send USDC from an external wallet or exchange

The document can be a Google Docs or another format.

Create a customer

To create a customer, make a POST request using the Add a customer endpoint.

 curl -X POST https://api.gravv.xyz/v1/customers \
  -H "Api-Key: grvSec_sandbox_6f72cfc99581469f834fb13015130a966f72cfc99581zB77Ij" \
  -H 'Idempotency-Key: 979879887678789_attempt_1' \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Bode",
    "last_name": "Thomas",
    "middle_name": "Olaoye",
    "email": "[email protected]",
    "phone": "+2348069867745",
    "type": "individual",
    "gender": "male",
    "date_of_birth": "2024-04-16",
    "address": {
      "address_line1": "Same Global Housing Estate",
      "city": "Lokogoma",
      "country": "NG",
      "postal_code": "900107",
      "state": "NG-FC"
    }
  }'

_first_name and last_name are required fields. middle_name is optional and should only be provided if it appears in the customer’s verification documents.

After sending the request, you will receive a response containing the customer details and their id. Save id from the response in your document as source account customer_id:

{
  "data": {
    "address": {
      "address_line1": "Same Global Housing Estate",
      "city": "Lokogoma",
      "country": "NG",
      "postal_code": "900107",
      "state": "FCT"
    },
    "date_of_birth": "1992-04-16",
    "email": "[email protected]",
    "first_name": "Bode",
    "gender": "male",
    "id": "d12ded01-9081-4a3c-a76c-70654f0a0175",
    "last_name": "Thomas",
    "middle_name": "Olaoye",
    "phone": "+2348069867745",
    "status": "active",
    "type": "individual"
  },
  "error": null
}

Initiate Know Your Customer (KYC)

After creating your customer, the next step is to initiate a KYC to verify the customer. You can do this with the Start KYC Verification endpoint. For this, you will need your source account customer_id:

curl --request POST \
     --url https://api.gravv.xyz/v1/risk/start-kyc \
     --header 'Api-Key: grvSec_sandbox_6f72cfc99581469f834fb13015130a966f72cfc99581zB77Ij' \
     --header 'Idempotency-Key: 979879887678789_attempt_1' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "kyc_level": "basic",
  "customer_id": "d12ded01-9081-4a3c-a76c-70654f0a0175"
}
'

After sending the request, you will get a response similar to this:

{
  "data": {
    "applicant_id": "68e4e0dda90f5ec3a13f21ef",
    "external_user_id": "d12ded01-9081-4a3c-a76c-70654f0a0175",
    "kyc_level": "basic",
    "review_status": "pending",
    "status": "success"
  },
  "error": null
}

Create an account for a customer

You can now Create an account for the customer. To do this, you will need your source account customer_id:

curl --request POST \
     --url https://api.gravv.xyz/v1/accounts \
     --header 'Api-Key: grvSec_sandbox_6f72cfc99581469f834fb13015130a966f72cfc99581zB77Ij' \
     --header 'Idempotency-Key: 979879887678789_attempt_1' \
     --header 'content-type: application/json' \
     --data '
{
  "currency": "USD",
  "type": "regular",
  "blockchain_network": "polygon",
  "label": "Bode Thomas",
  "customer_id": "d12ded01-9081-4a3c-a76c-70654f0a0175"
}
'

After sending the request, you will get a response that includes a wallet address and virtual account details. This gives the customer multiple options to receive payments:

{
  "data": {
    "assets": [
      {
        "balance": "0",
        "decimals": 0,
        "symbol": "USDC"
      }
    ],
    "balance": "0.00",
    "blockchain_network": "polygon",
    "capabilities": [
      "transfer",
      "receive",
      "remittance"
    ],
    "currency": "USD",
    "customer_id": "d12ded01-9081-4a3c-a76c-70654f0a0175",
    "date_created": "2025-10-07T09:49:23Z",
    "id": "a4d83e55-435e-41c9-9a0b-dcb99f690c95",
    "label": "Bode Thomas",
    "status": "active",
    "tenant_id": "cd90c45c-fa78-4624-a80a-642be301c812",
    "tenant_name": "Dahmoh",
    "tier": "",
    "type": "regular",
    "virtual_account_bank_account_number": "900300758080",
    "virtual_account_bank_address": "1800 North Pole St., Orlando, FL 32801",
    "virtual_account_bank_beneficiary_address": "1206 BEAR CREEK RD APT 1100, Hung, NJ 12345, US",
    "virtual_account_bank_name": "Bank of Nowhere",
    "virtual_account_bank_routing_number": "101019644",
    "virtual_account_id": "73cea894-bca7-43e2-b278-02bd6d991e2e",
    "wallet_address": "0xf73bdd069dc31aa8f334b177b175936ba98237a2"
  },
  "error": null
}

Notice that the response contains both customer_id and id. The customer_id is the same as the source account customer_id that you saved earlier. The id, on the other hand, is a unique identifier for the customer's account. Save the id as source account_id in your document. Then save the wallet_address as source account wallet_address in your document.

Fund the customer's account

Now fund the customer account using the wallet address. To do this, send USDC from an external wallet or exchange on the Polygon blockchain network to the source account wallet_address.

Ensure you are sending USDC on the Polygon network, not on Ethereum or other blockchain networks. The transaction settles within a few minutes, depending on network congestion.

Confirm the customer's account balance

Now that the Customer's account is funded, the received money will reflect in the customer's account balance. To confirm this, use the source account_id with the Get a single account endpoint to retrieve the customer’s account information:

curl --request GET \
     --url https://api.gravv.xyz/v1/accounts/a4d83e55-435e-41c9-9a0b-dcb99f690c95 \
     --header 'Api-Key: grvSec_sandbox_6f72cfc99581469f834fb13015130a966f72cfc99581zB77Ij'

You will get a response showing the customer's account balance:

{
  "data": {
    "assets": [
      {
        "balance": "100",
        "decimals": 0,
        "symbol": "USDC"
      }
    ],
    "balance": "100.00",
    "blockchain_network": "polygon",
    "capabilities": [
      "transfer",
      "receive",
      "remittance"
    ],
    "currency": "USD",
    "customer_id": "d12ded01-9081-4a3c-a76c-70654f0a0175",
    "date_created": "2025-10-07T09:49:23Z",
    "id": "a4d83e55-435e-41c9-9a0b-dcb99f690c95",
    "label": "Bode Thomas",
    "status": "active",
    "tenant_id": "cd90c45c-fa78-4624-a80a-642be301c812",
    "tenant_name": "Dahmoh",
    "tier": "",
    "type": "regular",
    "virtual_account_bank_account_number": "900300758080",
    "virtual_account_bank_address": "1800 North Pole St., Orlando, FL 32801",
    "virtual_account_bank_beneficiary_address": "1206 BEAR CREEK RD APT 1100, Hung, NJ 12345, US",
    "virtual_account_bank_name": "Bank of Nowhere",
    "virtual_account_bank_routing_number": "101019644",
    "virtual_account_id": "73cea894-bca7-43e2-b278-02bd6d991e2e",
    "wallet_address": "0xf73bdd069dc31aa8f334b177b175936ba98237a2"
  },
  "error": null
}

Initiate a transfer to another account

Now that you've confirmed the Customer's account balance, you can initiate a Transfer from the customer account to a destination account. Any account created through the Create an account endpoint is an Internal Account.

Since you are transferring to an Internal Account here, all you need is the source account customer_id, source account_id, and the account id of the destination account:

  1. Follow the instructions in Create a customer, Initiate Know Your Customer (KYC), and Create an account for a customer to create a destination account.

Use different personal details, such as names and email address, for this second customer.

  1. Save the id from the Create an account for a customer response as destination account_id.
  2. Prepare the following values for the transfer request:
  • source account customer_id
  • source account_id
  • destination account_id
  1. Send the transfer request using the prepared values:
curl --request POST \
     --url https://api.gravv.xyz/v1/transfer \
     --header 'Api-Key: grvSec_sandbox_6f72cfc99581469f834fb13015130a966f72cfc99581zB77Ij' \
     --header 'Idempotency-Key: 979879887678789_attempt_1' \
     --header 'content-type: application/json' \
     --data '
{
  "source": {
    "source_type": "internal_account",
    "id": "a4d83e55-435e-41c9-9a0b-dcb99f690c95"
  },
  "destination": {
    "destination_type": "internal_account",
    "id": "d33981df-26d6-4905-9557-aacccd363adb"
  },
  "amount": 100,
  "description": "transfer testing",
  "customer_id": "d12ded01-9081-4a3c-a76c-70654f0a0175",
  "client_reference": "987908790"
}
'

Congratulations🎉! You’ve completed your first Gravv integration. You’ve experienced the core capabilities of the Gravv API. You can now build on this foundation to create payment solutions for your users.