Set up your card account
Open the one card account that backs every card your business issues, find its id, and send it with every card activation.
This page shows how to open your card account and find its id. One card account backs every card you issue. A card account is an account of type card, in USD, that belongs to your business, not to each cardholder. You open it once. Then you send its id as account_id every time you activate cards for a customer. This is step 0 of every card guide.
A money example. Brightleaf, a savings app, opens its card account on Monday. On Tuesday it activates cards for Ada and for Chidi, sending the same account_id both times. Ada's card later holds 150 USD and Chidi's holds 40 USD. Each card has its own balance, and Brightleaf's one card account backs both.
Rules
| Rule | Detail |
|---|---|
| One per business | The API refuses a second card account with card account already exists for customer (account_id: <id>) |
| Owned by your business | Open it with your business's own customer id. The API refuses an end customer's id |
| USD | Open it in USD. Only the banks lead_bank and cross_river_bank offer card accounts. Send one of them as bank |
Starts pending |
It becomes active once the bank has set it up. Cards accept only an active card account |
| Not one per cardholder | Do not open a card account for each customer. To give a card its own balance, use funding.mode own when you issue it |
| v1 only | Open it with POST /v1/accounts, the one v1 accounts call the docs still use. POST /v2/accounts cannot open a working card account yet. In sandbox it stays pending, and it allows a second card account |
Open it in the Dashboard
In the Dashboard, go to Accounts, then Create account, and choose Cards Account. The Dashboard hides this option once your business has a card account.
Open it with the API
1. Find your business's own customer id
Your business has its own customer record, separate from your end customers. GET /v1/customers does not list it. Read it from one of your own accounts. An account whose category is main has it in customer_id.
curl --request GET \
--url 'https://api.gravv.xyz/v1/accounts?items_per_page=100' \
--header 'Api-Key: <API_KEY>'
{
"data": {
"items": [
{
"id": "2b7d4e1a-9c3f-4a8b-b6d2-5e0f1a2b3c4d",
"customer_id": "0f3a9c1e-5b7d-4e2a-8c6f-1d9e3b5a7c20",
"type": "regular",
"category": "main",
"currency": "USD",
"status": "active"
}
]
},
"error": null
}
Keep customer_id from a main account. Accounts with category sub_account belong to your customers.
2. Check you have no card account yet
curl --request GET \
--url 'https://api.gravv.xyz/v1/accounts?account_type=card' \
--header 'Api-Key: <API_KEY>'
If an account comes back, use its id and skip step 3.
3. Open the card account
curl --request POST \
--url https://api.gravv.xyz/v1/accounts \
--header 'Api-Key: <API_KEY>' \
--header 'Idempotency-Key: b766afa9-e0f0-48f0-b14d-4ab4a2408351' \
--header 'Content-Type: application/json' \
--data '
{
"type": "card",
"currency": "USD",
"bank": "lead_bank",
"blockchain_network": "polygon",
"label": "Cards",
"customer_id": "0f3a9c1e-5b7d-4e2a-8c6f-1d9e3b5a7c20"
}
'
The answer has "status": "pending". If you use a scoped API key, it needs the account:create scope.
4. Wait until it is active
Wait for the account.activated webhook, or read the account until status is active:
curl --request GET \
--url https://api.gravv.xyz/v1/accounts/9b40be8d-9d74-4d2a-8897-dea3ef80ad23 \
--header 'Api-Key: <API_KEY>'
The bank sets the account up in the background, so there is no fixed wait time.
Use it for every card
To find the card account at any time, list your active card accounts:
curl --request GET \
--url 'https://api.gravv.xyz/v1/accounts?account_type=card&status=active' \
--header 'Api-Key: <API_KEY>'
Send its id as provider_data.account_id each time you activate cards for a customer, whoever the customer is. If you leave account_id out, the activation fails with cards service: internal server error.
The card account's own network does not decide the card's network. Read each card's blockchain_network with Get card before you fund it.
What can go wrong
| Response | Why | Fix |
|---|---|---|
400 failed to create internal account: card accounts cannot be created for this customer — this account type is reserved for the tenant |
You sent an end customer's id | Send your business's own customer id (step 1) |
400 failed to create internal account: card account already exists for customer (account_id: <id>) |
Your business already has a card account | Use that id |
400 failed to create internal account: kyc validation failed: … |
Your business's own verification is not complete | Contact support |
400 cards service: account must be a card account, but this account's type is "regular" |
The activation sent the id of an account that is not your card account | Send the card account's id |
400 cards service: account must be active to be used for cards, but its status is "pending" |
The card account is not ready yet | Wait for account.activated |
400 cards service: account is not operated by the authenticated tenant |
The id belongs to another business, or to the other environment | Use your own card account, from the same environment as your key |
400 cards service: internal server error on activation |
You left out account_id |
Always send account_id |
Sandbox and live are separate. Open a card account in each, and use a grvSec_sandbox_ key for sandbox.