---
title: "Customers and KYC"
description: "Choose the recipe for creating a person or a business, verifying them, fixing a rejection, downloading a document, and the limits that apply once KYC passes."
---
Use these recipes to get a customer ready to hold and move money. You create the customer, verify their identity (KYC) and fix what goes wrong. Every account and every payout starts here, because Gravv opens an account only for a customer whose `basic` KYC is `completed`.

**Money example.** Amara, a nurse in Lagos, signs up with your app. Before KYC, the standard limits let her move 500.00 USD a day. She passes the hosted ID check, her KYC is `completed`, and the limit becomes 50,000.00 USD a day. You can now open the USD account that her employer pays her 1,200.00 USD salary into.

## Choose your recipe

| You want to | Status | Recipe |
| :-- | :-- | :-- |
| Create a person and verify them on Gravv's hosted page, with a liveness check | Available | [Verify a person on a hosted page](/recipes/customers-and-kyc/verify-a-person-on-a-hosted-page) |
| Verify a person with an ID and selfie you already hold | Available | [Verify a person with documents you upload](/recipes/customers-and-kyc/verify-a-person-with-documents-you-upload) |
| Create a company with its owners and directors, and verify all of them | Available | [Onboard a business and its owners](/recipes/customers-and-kyc/onboard-a-business-and-its-owners) |
| Try again after KYC `failed` | Available | [Resubmit KYC after a rejection](/recipes/customers-and-kyc/resubmit-kyc-after-a-rejection) |
| Get a copy of an uploaded ID for a compliance review | Available | [Download a KYC document](/recipes/customers-and-kyc/download-a-kyc-document) |
| Know how much a customer can send, and raise it | Available | [Raise a customer's limits with KYC](/recipes/customers-and-kyc/raise-a-customers-limits-with-kyc) |
| A payout paused for the sender's name or date of birth | Available | [Avoid a payout pause for sender details](/recipes/customers-and-kyc/avoid-a-payout-pause-for-sender-details) |

The `intermediate` KYC level is **Not yet available**. Every customer has the row, but no API call starts it. Card KYC with liveness is in the [card KYC flow](/platform/cards/card-kyc/overview).

## Which way to verify

| Customer | Hosted page (`/kyc/start`) | Documents you upload (`/kyc/upload-document` + `/kyc/start-s2s`) |
| :-- | :-- | :-- |
| A person | Available, with a liveness check | Available, no liveness check |
| A business's associated person | Available, with the person's own id | Available, with the person's own id |
| A business | Available, after every associated person is verified | Available, with four company documents, after every person is verified |
| On a business Gravv set up for automatic verification | Not supported. The API refuses the start | Available. KYC completes from the documents |

Gravv bills a hosted start once, and a restart after a failure or an expired link is free. Gravv bills every server-to-server start again.

## Rules every recipe relies on

- Send every request to one host, `https://api.gravv.xyz`, with the `Api-Key` header. A key that starts with `grvSec_sandbox_` reaches sandbox; any other key is live. Sandbox and live data are separate, so an id from one is "not found" in the other.
- Every POST needs its own new `Idempotency-Key`. Gravv replays a 4xx response for 24 hours under its key, so **use a new key after you fix a request**. Keep the same key only after a timeout or a 5xx.
- Customer and KYC errors return `{"data": null, "error": "<text>"}`, with `error` as a string. KYC error texts start with a code such as `INVALID_REQUEST:`. Gateway errors, such as a reused key, carry an object instead.
- A scoped key needs `customer:create` to create, `customer:update` to update, upload or download, and `customer:update` or `customer:kyc_override` to start KYC.
- The decision that counts is `kyc[type=basic].status` on [`GET /v1/customers/{customer_id}`](/api-reference/customers/get-v1-customers-customer-id), or the [`customer.kyc.status.*` webhook](/platform/webhooks/event-catalogue#customers-and-kyc). Deduplicate webhooks on the body's `event_id`.
- **Sandbox KYC does not complete today.** Create, upload, start and the hosted link work. The `basic` row stays `pending` and Gravv sends no outcome webhook, so you cannot finish steps that need a verified customer in sandbox yet.
