Create a card
Issue the first card after a live approval, or an extra card for a cardholder, with its daily limit and balance mode.
Create card issues a card for a cardholder whose card application is approved. Use it in two cases:
- In live, once, to issue the first card after the application is
approved. - In sandbox and live, to give a cardholder another card (up to 10 that are not blocked).
In sandbox, Gravv issues the first virtual card during activation, so you do not call this endpoint for it.
A money example. Ada's live application is approved. You issue her a virtual card with card_limit 300, so she can spend up to 300 USD a day. Later you give her a second card for subscriptions with its own balance and a 50 USD daily limit, and move 30 USD onto it. Her main card's balance is unchanged.
Issue a card
curl --request POST \
--url https://api.gravv.xyz/v1/cards \
--header 'Api-Key: <API_KEY>' \
--header 'Idempotency-Key: 4c457369-8091-4908-abff-743ac619df07' \
--header 'Content-Type: application/json' \
--data '
{
"customer_id": "5b0f6c1e-2a8f-4c39-9d0e-0c7e3b9a1f42",
"card_type": "virtual",
"card_limit": 300,
"name_on_card": "Ada Obi"
}
'
{
"data": {
"message": "Card creation request is processing",
"status": true,
"id": "a14ec356-f33d-4384-ba68-4d9bfa19765b",
"fee_charged": false
},
"error": null
}
| Field | Rule |
|---|---|
customer_id |
The cardholder |
card_type |
virtual. physical is Not yet available. See Physical card shipping |
card_limit |
Daily limit in whole US dollars, a JSON number above 0. Gravv drops decimals (300.99 becomes 300). Change it later with Manage card status |
name_on_card |
Up to 100 characters |
funding |
Optional. {"mode": "own"} gives the card its own balance. {"mode": "shared"} or no funding spends from the cardholder's existing balance |
shipping_address |
Physical cards only |
The first card's id equals the application id. Each card gets a 4-digit PIN at creation. Read it with Get card PIN. Gravv sends no webhook for a new card, so read the card with Get card.
Extra cards
Each extra card needs its own new Idempotency-Key, because the key identifies that issuance. The API refuses a request without a key, and it refuses the same key with a different body with 422 idempotency_key_reused.
A cardholder can hold up to 10 cards that are not blocked. A replacement for a blocked card that you send without funding spends from the same balance as the blocked card.
What can go wrong
| Response | Why | Fix |
|---|---|---|
400 card application is not yet approved! |
Live application still under review | Wait for approved, then retry with a new key |
400 card application not found! |
You never activated cards for this customer | Activate cards first |
400 customer already holds the maximum of 10 cards |
The customer has reached the 10-card limit | Block a card the customer no longer uses |
400 CardLimit is required, NameOnCard is required, CardType must be one of: physical virtual |
A missing or wrong field. The error uses internal names, so CardLimit is card_limit |
Fix the field and use a new key |
400 internal server error |
Usually a number sent as a string ("card_limit": "300") |
Send numbers as numbers and use a new key |
400 funding.mode must be "shared" or "own" |
Bad mode | Use one of the two |
400 funding.card_group_id is only valid when funding.mode is "shared" |
card_group_id with own |
Drop it |
400 this card's balance is a new provider account whose application is <status>; retry with the same Idempotency-Key once it is approved |
In live, a card with funding.mode own needs its own approval |
Wait for the approval, then retry with the same key and body once 24 hours have passed since the first attempt (Gravv replays the 400 for 24 hours). A new key starts another card. If 24 hours is too long, contact support |