Open a second account
Add an account for a customer who already has one at the same bank, and know what to do when you reach the per-customer limit and get a 409.
Add an account for a customer who already has one at the same bank, and learn what to do when you reach the per-customer limit and get a 409.
API version: v2.
Who it is for. A platform adding a GBP account for a customer who already has USD and EUR accounts, or a platform that got a 409 on create.
Status. Available, within each option's max_accounts_per_customer.
Money example
Brightleaf Studio already holds five wallet-backed accounts at one option: three USD, one EUR and one GBP.
- You try to open a sixth account, in EUR, and get 409
maximum number of USD/EUR/GBP accounts … (5). - You reuse one of the five, or ask Gravv support to raise this customer's limit.
- After support raises the limit, the same create request succeeds with a new idempotency key.
Before you start
List the customer's accounts. Count the pending and active accounts at the same option and account type.
curl --request GET \
--url 'https://api.gravv.xyz/v2/accounts?customer_id=3a4b5c6d-7e8f-4a9b-8c0d-1e2f3a4b5c6d&bank_code=<bank_code>' \
--header 'Api-Key: <API_KEY>'
const response = await fetch("https://api.gravv.xyz/v2/accounts?customer_id=3a4b5c6d-7e8f-4a9b-8c0d-1e2f3a4b5c6d&bank_code=<bank_code>", {
method: "GET",
headers: {
"Api-Key": process.env.GRAVV_API_KEY,
},
});
console.log(response.status, await response.json());
import os
import requests
response = requests.get(
"https://api.gravv.xyz/v2/accounts?customer_id=3a4b5c6d-7e8f-4a9b-8c0d-1e2f3a4b5c6d&bank_code=<bank_code>",
headers={
"Api-Key": os.environ["GRAVV_API_KEY"],
},
)
print(response.status_code, response.json())
Find out what is required
- The limit. Read
max_accounts_per_customerin capabilities, with this customer'scustomer_id.nullmeans no limit. A limit counts all currencies of one option together, such as USD, EUR and GBP. - Whether the bank knows the customer. Read requirements with
customer_idandbank_code.has_existing_ref: truemeans the bank already has this customer. The root fields disappear fromfields, and your create request must not senddata.root. - An open application. If requirements returns
existing_application, an application is still open at that bank. Finish it first. See Unblock an application.
Steps
1. Open the account on the existing relationship
With has_existing_ref: true, send only the top-level fields. Gravv applies no prefill and no defaults on this path, so account_type and category are required. Gravv drops any new document or new party you send, and does not upload it.
curl --request POST \
--url https://api.gravv.xyz/v2/accounts \
--header 'Api-Key: <API_KEY>' \
--header 'Idempotency-Key: 239eff27-b43e-4c5a-bf9e-2a9505c0b70a' \
--header 'Content-Type: application/json' \
--data '
{
"customer_id": "3a4b5c6d-7e8f-4a9b-8c0d-1e2f3a4b5c6d",
"customer_type": "business",
"currency": "GBP",
"account_type": "operating",
"category": "sub_account",
"bank_code": "<bank_code>",
"network": "polygon",
"label": "Brightleaf GBP"
}
'
const response = await fetch("https://api.gravv.xyz/v2/accounts", {
method: "POST",
headers: {
"Api-Key": process.env.GRAVV_API_KEY,
"Idempotency-Key": "239eff27-b43e-4c5a-bf9e-2a9505c0b70a",
"Content-Type": "application/json",
},
body: JSON.stringify({
"customer_id": "3a4b5c6d-7e8f-4a9b-8c0d-1e2f3a4b5c6d",
"customer_type": "business",
"currency": "GBP",
"account_type": "operating",
"category": "sub_account",
"bank_code": "<bank_code>",
"network": "polygon",
"label": "Brightleaf GBP"
}),
});
console.log(response.status, await response.json());
import os
import requests
response = requests.post(
"https://api.gravv.xyz/v2/accounts",
headers={
"Api-Key": os.environ["GRAVV_API_KEY"],
"Idempotency-Key": "239eff27-b43e-4c5a-bf9e-2a9505c0b70a",
"Content-Type": "application/json",
},
json={
"customer_id": "3a4b5c6d-7e8f-4a9b-8c0d-1e2f3a4b5c6d",
"customer_type": "business",
"currency": "GBP",
"account_type": "operating",
"category": "sub_account",
"bank_code": "<bank_code>",
"network": "polygon",
"label": "Brightleaf GBP",
},
)
print(response.status_code, response.json())
The API returns {"account_id": "…", "status": "pending"}. Follow the account as you would a first account.
What can go wrong
| Response | Why | Fix |
|---|---|---|
409 this customer already holds the maximum number of USD/EUR/GBP accounts permitted for this account type (5) |
The customer's pending and active accounts at this option and type reached the limit |
Reuse an account, or ask support to raise this customer's limit |
409 this customer already holds the maximum number of EUR/GBP accounts permitted for this account type (1) |
The customer already has the one account the one-IBAN option allows | Use that account |
409 customer already has an application in progress for this bank |
An earlier application is open | Unblock it or wait |
409 this account provider is currently disabled for this account |
Gravv switched this option off for your business or this customer | Use another option, or contact support |
400 this customer already has an existing reference at the resolved bank; root-level fields are no longer accepted for it … |
You sent data.root with an existing reference |
Remove data.root |
400 on a missing category or account_type |
This path applies no defaults | Always send both |
| The Dashboard says "already has an application open at this bank" | The Dashboard shows that text for every 409 | Read the API's 409 message. It is usually the limit |
Do not retry a 409 with the same body.
Webhooks you will receive
You receive the same events as for a first account, applications.accounts.*. See Account application events.
Testing in sandbox
Limits apply in sandbox too, and sandbox and live counts are separate. Sandbox limits can differ from live, so read them from capabilities.