Open a wallet-backed USD account for a business
Open a USD business account with US bank details, declaring its owners, directors and signers, whose deposits arrive as USDC.
Open a USD account with US bank details for a business, and declare its owners, directors and signers. Deposits to the account arrive as USDC.
API version: v2.
Who it is for. A UK export company that sells to US buyers. It wants their USD payments to arrive as USDC that it can convert or pay out at once.
Status. Available for businesses in the countries each option serves. The default USD option accepts only a US EIN as the company's tax id.
Money example
Acme Exports Ltd sells goods for 18,500.00 USD.
- The US buyer wires 18,500.00 USD to Acme's account number and routing number.
- The bank converts the payment to USDC in the account's wallet on polygon.
- Gravv sends
transfer.inflow.deposit_settled, and Acme's balance shows the credit.
Before you start
- The business customer exists with its associated persons. Save each
associated_persons[].id. - Every associated person, and then the business, has
basicKYCcompleted. See Onboard a business and its owners. - Capabilities with
customer_type=business¤cy=USDlist a wallet-backed option. - Collect the company documents from the business as files. For each owner, director or signer, collect their ID and their ownership, control and signing roles.
Find out what is required
Read requirements with customer_type=business and country set to the incorporation country. Every option here takes 1 to 10 parties.
| The default USD option | The USD, EUR and GBP option | The EUR and USD option | |
|---|---|---|---|
| Company (root) | legal_name, business_type, industry, registration_number, incorporation_country, incorporation_date, tax_id_type (ein only), tax_id_number, business_description, business_address |
legal_name, dba_name, business_description, business_type, incorporation_country, email, phone_daytime, tax_id_type, tax_id_number, business_address (state only in the US) |
legal_name, registration_number, incorporation_country, incorporation_date and the form's other company fields. website with https:// |
| Each party | Names, date_of_birth, email, phone_daytime, citizenship_country, has_ownership, has_control, is_signer, residential_address. A party with ownership also needs ownership_percentage (0 to 100). A US citizen also needs a tax id |
Names, date_of_birth, email, phone_daytime, citizenship_country, has_ownership, has_control, is_signer, is_director. ownership_percentage is 1 to 100, and at least 25 for a party with control |
Names, date_of_birth, email, phone_daytime, tax_residence_country, has_ownership, has_control, is_signer, residential_address |
| Company documents | articles_of_incorporation, ownership_document, proof_of_address, control_structure |
articles_of_incorporation, ownership_document, proof_of_address |
articles_of_incorporation, ownership_document, proof_of_address, control_structure |
| Party documents | One identity document and proof_of_address each |
One identity document each | One identity document each |
The API refuses P.O. Box addresses. A US-incorporated company sends tax_id_type ein. If the requirements response differs from this table, trust the requirements response.
Steps
1. Open the account
Declare a person who is already on the customer record by id. Send only what the record lacks, such as flags, percentages, documents and anything that differs. Gravv fills the person's names, date of birth, email, phone, citizenship_country and address from the record. It takes citizenship_country from their address country.
curl --request POST \
--url https://api.gravv.xyz/v2/accounts \
--header 'Api-Key: <API_KEY>' \
--header 'Idempotency-Key: 8d4631bf-8fbc-4144-8e2c-e572ca903627' \
--header 'Content-Type: application/json' \
--data '
{
"customer_id": "9a1e4c77-2f3b-4d8e-b6a0-5c3e8f9d1b22",
"customer_type": "business",
"currency": "USD",
"account_type": "operating",
"category": "sub_account",
"bank_code": "<bank_code>",
"network": "polygon",
"label": "Acme USD",
"data": {
"root": {
"legal_name": "Acme Exports Ltd",
"business_type": "private limited company",
"industry": "wholesale_trade",
"registration_number": "12345678",
"incorporation_country": "GB",
"incorporation_date": "2015-03-01",
"tax_id_type": "ein",
"tax_id_number": "981234567",
"business_description": "Exports industrial pumps to buyers in North America",
"business_address": {
"address_line": "1 Finsbury Avenue",
"city": "London",
"state": "GB-LND",
"postal_code": "EC2M 2PF",
"country": "GB"
}
},
"parties": [
{
"id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
"phone_daytime": "+447912345678",
"citizenship_country": "GB",
"has_ownership": true,
"ownership_percentage": 60,
"has_control": true,
"is_signer": true,
"residential_address": {
"address_line": "14 Deansgate",
"city": "Manchester",
"state": "GB-MAN",
"postal_code": "M3 2BW",
"country": "GB"
},
"documents": [
{"document_type": "passport", "issuing_country": "GB", "number": "548102937", "issued_date": "2021-07-01", "expiration_date": "2031-06-30", "filename": "owner-passport.jpg", "content": "<base64>"},
{"document_type": "proof_of_address", "issuing_country": "GB", "filename": "owner-bill.pdf", "content": "<base64>"}
]
}
],
"documents": [
{"document_type": "articles_of_incorporation", "issuing_country": "GB", "filename": "articles.pdf", "content": "<base64>"},
{"document_type": "ownership_document", "issuing_country": "GB", "filename": "shareholders.pdf", "content": "<base64>"},
{"document_type": "proof_of_address", "issuing_country": "GB", "filename": "company-bill.pdf", "content": "<base64>"},
{"document_type": "control_structure", "issuing_country": "GB", "filename": "org-chart.pdf", "content": "<base64>"}
]
}
}
'
const response = await fetch("https://api.gravv.xyz/v2/accounts", {
method: "POST",
headers: {
"Api-Key": process.env.GRAVV_API_KEY,
"Idempotency-Key": "8d4631bf-8fbc-4144-8e2c-e572ca903627",
"Content-Type": "application/json",
},
body: JSON.stringify({
"customer_id": "9a1e4c77-2f3b-4d8e-b6a0-5c3e8f9d1b22",
"customer_type": "business",
"currency": "USD",
"account_type": "operating",
"category": "sub_account",
"bank_code": "<bank_code>",
"network": "polygon",
"label": "Acme USD",
"data": {
"root": {
"legal_name": "Acme Exports Ltd",
"business_type": "private limited company",
"industry": "wholesale_trade",
"registration_number": "12345678",
"incorporation_country": "GB",
"incorporation_date": "2015-03-01",
"tax_id_type": "ein",
"tax_id_number": "981234567",
"business_description": "Exports industrial pumps to buyers in North America",
"business_address": {
"address_line": "1 Finsbury Avenue",
"city": "London",
"state": "GB-LND",
"postal_code": "EC2M 2PF",
"country": "GB"
}
},
"parties": [
{
"id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
"phone_daytime": "+447912345678",
"citizenship_country": "GB",
"has_ownership": true,
"ownership_percentage": 60,
"has_control": true,
"is_signer": true,
"residential_address": {
"address_line": "14 Deansgate",
"city": "Manchester",
"state": "GB-MAN",
"postal_code": "M3 2BW",
"country": "GB"
},
"documents": [
{
"document_type": "passport",
"issuing_country": "GB",
"number": "548102937",
"issued_date": "2021-07-01",
"expiration_date": "2031-06-30",
"filename": "owner-passport.jpg",
"content": "<base64>"
},
{
"document_type": "proof_of_address",
"issuing_country": "GB",
"filename": "owner-bill.pdf",
"content": "<base64>"
}
]
}
],
"documents": [
{
"document_type": "articles_of_incorporation",
"issuing_country": "GB",
"filename": "articles.pdf",
"content": "<base64>"
},
{
"document_type": "ownership_document",
"issuing_country": "GB",
"filename": "shareholders.pdf",
"content": "<base64>"
},
{
"document_type": "proof_of_address",
"issuing_country": "GB",
"filename": "company-bill.pdf",
"content": "<base64>"
},
{
"document_type": "control_structure",
"issuing_country": "GB",
"filename": "org-chart.pdf",
"content": "<base64>"
}
]
}
}),
});
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": "8d4631bf-8fbc-4144-8e2c-e572ca903627",
"Content-Type": "application/json",
},
json={
"customer_id": "9a1e4c77-2f3b-4d8e-b6a0-5c3e8f9d1b22",
"customer_type": "business",
"currency": "USD",
"account_type": "operating",
"category": "sub_account",
"bank_code": "<bank_code>",
"network": "polygon",
"label": "Acme USD",
"data": {
"root": {
"legal_name": "Acme Exports Ltd",
"business_type": "private limited company",
"industry": "wholesale_trade",
"registration_number": "12345678",
"incorporation_country": "GB",
"incorporation_date": "2015-03-01",
"tax_id_type": "ein",
"tax_id_number": "981234567",
"business_description": "Exports industrial pumps to buyers in North America",
"business_address": {
"address_line": "1 Finsbury Avenue",
"city": "London",
"state": "GB-LND",
"postal_code": "EC2M 2PF",
"country": "GB",
},
},
"parties": [
{
"id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
"phone_daytime": "+447912345678",
"citizenship_country": "GB",
"has_ownership": True,
"ownership_percentage": 60,
"has_control": True,
"is_signer": True,
"residential_address": {
"address_line": "14 Deansgate",
"city": "Manchester",
"state": "GB-MAN",
"postal_code": "M3 2BW",
"country": "GB",
},
"documents": [
{
"document_type": "passport",
"issuing_country": "GB",
"number": "548102937",
"issued_date": "2021-07-01",
"expiration_date": "2031-06-30",
"filename": "owner-passport.jpg",
"content": "<base64>",
},
{
"document_type": "proof_of_address",
"issuing_country": "GB",
"filename": "owner-bill.pdf",
"content": "<base64>",
},
],
},
],
"documents": [
{
"document_type": "articles_of_incorporation",
"issuing_country": "GB",
"filename": "articles.pdf",
"content": "<base64>",
},
{
"document_type": "ownership_document",
"issuing_country": "GB",
"filename": "shareholders.pdf",
"content": "<base64>",
},
{
"document_type": "proof_of_address",
"issuing_country": "GB",
"filename": "company-bill.pdf",
"content": "<base64>",
},
{
"document_type": "control_structure",
"issuing_country": "GB",
"filename": "org-chart.pdf",
"content": "<base64>",
},
],
},
},
)
print(response.status_code, response.json())
The API returns {"account_id": "…", "status": "pending"}.
- If you send no
parties, Gravv declares every associated person on the record without flags, and the request fails validation on them. Declare parties yourself. - For a person not on the record, leave out
id, and send the form'snew_party_fields(names,date_of_birth,gender,email,phone_daytime,residential_address) with the party fields.
2. Follow it until it is active
Read GET /v2/accounts/{id}, or wait for applications.accounts.completed, as in the individual recipe. If the bank asks for a person's document later, upload it with that person's party_id. See Unblock an application.
What can go wrong
Every error in the individual recipe can happen here too. These errors are specific to businesses:
| Response | Why | Fix |
|---|---|---|
400 details.parties: required: requires at least 1 declared party |
You declared no parties, and the record has none | Declare at least one |
400 details.parties: too_many: accepts at most 10 declared parties |
You declared more than 10 | Declare at most 10 |
400 no person with id X is on this customer's record. People on the record: … |
The person id is wrong | Send an associated_persons[].id from GET /v1/customers/{customer_id} |
400 party id X is already declared at parties[0].id |
You declared the same person twice | Declare each person once |
400 details.party[0].ownership_percentage: required: is required |
A party has has_ownership: true without a percentage |
Add it |
400 on party[0].ownership_percentage (below 25 with control) |
A control person under the 25% threshold on that option | Fix the percentage or the flag |
400 on tax_id_type |
A US company did not send ein |
Send ein |
400 details.party[0].documents: required: requires document national_id, passport, … |
A party has no ID | Put the ID under that party's documents |
400 party_index is no longer supported for document attribution; … |
The request uses an old style | Nest the document under the party |
400 details.website: must start with http:// or https:// |
website is a bare domain |
Add the scheme |
400 customer_type=business does not match this customer's registered profile, which is individual. … |
customer_type is wrong |
Send the customer's type |
Webhooks you will receive
Gravv sends applications.accounts.pending, sometimes applications.accounts.blocked, then applications.accounts.completed or applications.accounts.failed. See Account application events.
Testing in sandbox
As for a person, sandbox calls the bank's own test system, and activation is not instant. Business KYC in sandbox needs the persons' KYC first. Their reviews do not complete today, so the create call cannot succeed in sandbox yet.