---
title: "Read account requirements"
description: "Use GET /v2/accounts/requirements to get the fields and documents a bank needs, and turn the form into a create request."
---
**API version:** v2.

Each bank asks for different data. [`GET /v2/accounts/requirements`](/api-reference/accounts-v2/get-v2-accounts-requirements) returns the form for one option. The form lists the fields, the documents and, for a business, the people (parties) to declare. Read it before you open the account, so the create call succeeds the first time.

**A money example.** Ada's 1,200.00 USD invoice needs a USD account. The default USD option for a GB individual asks for 13 fields (names, date of birth, email, phone, gender, citizenship, tax residence and a full address) and 2 documents (an identity document and a proof of address). You collect those once, and the account opens without a second round.

## Ask for the form

Always send `customer_type`, `currency`, `bank_code` and `country`. The create call picks the bank from the country inside your data, while this call picks it from the `country` parameter. Unless you send both `bank_code` and `country`, you can get the form of a different bank. Send `customer_id` too, to see what is already on file:

```bash title="Requirements request"
curl --request GET \
     --url 'https://api.gravv.xyz/v2/accounts/requirements?customer_type=individual&currency=USD&bank_code=<bank_code>&country=GB&customer_id=0b6f3c1e-2a4d-4c8e-9f10-7d2a6b5e4c33' \
     --header 'Api-Key: <API_KEY>'
```

Here is the response, trimmed to 3 fields and 2 suggestions (checked in sandbox):

```json title="Requirements response"
{
  "data": {
    "documents": [
      {"new_document_fields": ["document_type", "content", "issuing_country", "number", "issued_date", "expiration_date"], "required": true, "scope": "root", "types": ["national_id", "passport", "drivers_license", "permanent_resident_card", "employment_authorization", "other"]},
      {"new_document_fields": ["document_type", "content", "issuing_country"], "required": true, "scope": "root", "types": ["proof_of_address"]}
    ],
    "fields": [
      {"group": "identity", "is_predefined": true, "label": "First Name", "name": "first_name", "required": true, "scope": "root", "type": "string", "write_only": false},
      {"enum": "Gender", "group": "identity", "is_predefined": true, "label": "Gender", "name": "gender", "options": ["female", "male"], "required": true, "scope": "root", "type": "enum", "write_only": false},
      {"applies_when": {"field": "citizenship_country", "op": "eq", "value": "US"}, "group": "us_tax", "is_predefined": false, "label": "Tax ID Number", "name": "tax_id_number", "required": true, "scope": "root", "type": "string", "write_only": true}
    ],
    "has_existing_ref": false,
    "max_parties": null,
    "min_parties": null,
    "suggestions": {
      "documents": {"passport": {"message": "already on file for this customer; upload a new one to override it", "value": "passport"}},
      "fields": {"first_name": {"message": "on file for this customer; send this field to override it", "value": "Ada"}}
    },
    "token_options": [{"asset": "usdc", "network": "polygon"}, {"asset": "usdc", "network": "ethereum"}, {"asset": "usdc", "network": "solana"}]
  },
  "error": null
}
```

## Turn the form into a request

| The form says | Put it in the create body |
| :-- | :-- |
| a field with `scope` `root` | `data.root.<name>`. A dotted name is nested: `permanent_address.city` becomes `"permanent_address": {"city": "…"}` |
| a field with `scope` `party[*]` | every entry of `data.parties[]` (directors, owners, signers of a business) |
| `new_party_fields` | the fields for a person who is not on the customer record (no `id`) |
| a document with `scope` `root` | one entry in `data.documents[]`, of any one of the listed `types` |
| a document with `scope` `party[*]` | that party's own `documents[]` |
| `new_document_fields` | the keys a new upload carries: `document_type`, `content` (base64; JPEG, PNG or PDF; at most 2 MB, and in sandbox under 500 KB for all of one request's files), `issuing_country`, and `number`, `issued_date`, `expiration_date` for identity documents |
| `required: true` and no condition | always send it |
| `applies_when` | send it only when the condition is true for this customer, for example only for US citizens |
| `options` | the only accepted values |
| `write_only: true` | a secret, such as a tax number. The API never returns it |
| `is_predefined: true`, or the field is in `suggestions.fields` | already on the customer record. Leave it out and Gravv fills it, or send it to override |
| `suggestions.documents.<type>` | a document of that type is on file |
| `token_options` | the networks you can send as `network` |
| `min_parties`, `max_parties` | how many people a business must declare. `null` means none needed |
| `has_existing_ref: true` | the bank already knows this customer, so send no `data.root` |
| `existing_application` | an application is already open at this bank, so [fix that one](/platform/accounts/fix-a-blocked-application) instead |

These parts of the form are not yet live: a document with a `required_when` condition, a `metadata` object on a document, a `predefined` object, and the `autofill_tax_form` question. They exist only on a build that has not reached production. In production, every document carries `required` (`true`, or `false` when the bank fills a tax form itself). Sandbox already returns the new shape for some forms.

## Rules the form does not show

- **Top level, not in `data.root`.** Send `customer_id`, `customer_type`, `currency`, `account_type`, `category`, `label`, `bank_code`, `network` and `wallet_id` at the top level. The API refuses `network` or `wallet_id` inside `data.root`.
- **Always send `customer_type` and the routing country.** Send the routing country in `data.root`, as `citizenship_country` for a person or `incorporation_country` for a business. Gravv chooses the bank from your request before it fills in any missing fields.
- **Filled in for you.** If you leave them out, Gravv fills in names, `date_of_birth`, `email`, phone, `gender`, `legal_name`, `registration_number`, `business_description`, `business_type` and `industry`. A filled-in `citizenship_country` or `tax_residence_country` is the customer's address country, so send them when they differ. Gravv does not fill in the address, so send `permanent_address` yourself.
- **Documents on file.** If you send no documents, Gravv attaches the customer's documents on file. If you send even one, Gravv uses only what you send. To reuse a file, send `{"id": "<document id>"}` instead of `content`.
- **Registration type.** `registration_type` defaults from `customer_type`. Send it only for a joint or minor account.
- **Gender.** `gender` accepts `female` or `male` on these forms. If you created the customer with `other`, the form suggests `other` but refuses it. Ask the customer which value to send.
- **Old field names.** Gravv still maps old names such as `dob` or `ssn`. Send the name the form gives. Sending both returns `alias_conflict`.

## Errors

| Response | Why | Fix |
| :-- | :-- | :-- |
| 400 `Customer Type is required (and 1 other field; see details)` with `details.customer_type` and `details.currency` | Both are required | Send them |
| 400 `no account option is available for the requested combination (…)`, with `UNSUPPORTED_COMBINATION` in `details` | No option serves the values you sent. Also returned for an unknown `bank_code`, or a `bank_code` that does not serve that country or currency | Copy `bank_code`, `currency` and `country` from one option in [capabilities](/platform/accounts/find-an-account-option) |
| 400 `invalid request payload: unknown field "limit"` | Unknown query parameter | Send only the documented ones |
| A business form for an individual customer | The requirements call does not check `customer_type` against the record | Send the customer's own type. The create call refuses a mismatch |
| No `suggestions` although you sent `customer_id` | The customer lookup failed | Retry. The form itself is correct |

## Next

[Open the account](/platform/accounts/open-an-account) with the data you collected.
