---
title: "Create a card application"
---
Cards don't work the way accounts do. With an account you can create the account directly. With a card you can't: every card needs an **approved card application** behind it first. The application is where Gravv runs the customer's risk and compliance checks before any card is issued.

> 📘 Do I create the card directly, or apply first?
>
> You apply first. There's no direct "create card" shortcut like there is for accounts. In production you don't call the card application endpoint yourself either. You **activate the card feature**, and that creates the application for you. Once the application is approved, you call [Create a card](/platform/cards/create-a-card).

## How an application gets created

There are two ways to create a card application, and which one you use depends on the environment:

| Environment | How to create the application |
| :---------- | :---------------------------- |
| **Live** | Activate the card feature with [Activate feature](/api-reference/features/post-v1-risk-features-activate). Activating `virtual_cards` creates the application. |
| **Sandbox** | Activating the feature works here too, and is the recommended path. A standalone [Create card application](/api-reference/cards/post-v1-cards-applications-new) endpoint also exists for testing. It is not supported in Live, so build your integration around feature activation. |

Activating the feature is the one path that works in both environments, so use it everywhere.

## Before you start

The customer must already exist and have completed intermediate [KYC](/getting-started/know-your-customer). Intermediate KYC includes a selfie (liveness) check, which the card application depends on.

Then confirm the customer is ready with [Check feature eligibility](/platform/features/check-feature-eligibility) for `virtual_cards`. Eligibility returns `eligible: true` only when KYC is `completed` and you supply the required provider data shown below.

## Step 1: Activate the card feature

Call [Activate feature](/api-reference/features/post-v1-risk-features-activate) with `feature_id` set to `virtual_cards`. For cards, the `provider_data` object is required:

| Field | Type | Required | Description |
| :---- | :--- | :------- | :---------- |
| `annual_remuneration` | number | yes | Customer's expected annual inflow in USD |
| `estimated_monthly_limit` | number | yes | Expected monthly card spend in USD. Must be lower than `annual_remuneration` |
| `ip_address` | string | yes | IP address the request comes from |
| `account_id` | string | no | The card account that backs the card. Gravv derives it from your tenant's card account if you leave it out |

```bash title="activate the card feature"
curl --request POST \
     --url https://api.gravv.xyz/v1/risk/features/activate \
     --header 'Api-Key: <API_KEY>' \
     --header 'Idempotency-Key: activate_cards_001' \
     --header 'content-type: application/json' \
     --data '
{
  "customer_id": "9e3cccad-e9ae-47a0-81ee-063af0159310",
  "feature_id": "virtual_cards",
  "provider_data": {
    "annual_remuneration": 120000,
    "estimated_monthly_limit": 5000,
    "ip_address": "12.23.31.23"
  }
}
'
```

On success, the response confirms the feature is active and returns the `application_id` of the card application that was created:

```json title="activate the card feature response"
{
  "data": {
    "customer_id": "9e3cccad-e9ae-47a0-81ee-063af0159310",
    "feature_id": "virtual_cards",
    "status": "active",
    "activated_at": "2026-01-09T10:29:16.000Z",
    "data": {
      "application_id": "a14ec356-f33d-4384-ba68-4d9bfa19765b"
    }
  },
  "error": null
}
```

Save the `application_id`. You'll use it to track the application and, later, to confirm the card can be created.

### If liveness isn't complete yet

If the customer hasn't completed their selfie (liveness) check, activation can't finish. The response comes back with a `websdk_url` instead:

```json title="activation needs liveness"
{
  "data": {
    "customer_id": "9e3cccad-e9ae-47a0-81ee-063af0159310",
    "feature_id": "virtual_cards",
    "status": "pending_liveness",
    "websdk_url": "https://verify.gravv.xyz/liveness/abc123xyz"
  },
  "error": null
}
```

Redirect the customer to the `websdk_url` to finish verification, then call Activate feature again. Activation is idempotent, so retrying after the check is done returns the existing application rather than creating a second one.

## Step 2: Track the application status

A new application starts as `pending` while Gravv reviews it. Track it one of two ways:

- Listen for the [card webhook events](/platform/webhooks/card-events).
- Poll [Get card application](/api-reference/cards/get-v1-cards-applications-application-id) with the `application_id`. To list every application for the tenant, use [Get card applications](/api-reference/cards/get-v1-cards-applications).

```bash title="check application status"
curl --request GET \
     --url https://api.gravv.xyz/v1/cards/applications/{application_id} \
     --header 'Api-Key: <API_KEY>'
```

The `application_status` field tells you where the application stands:

| Status | What it means | What to do |
| :----- | :------------ | :--------- |
| `pending` | Under review | Wait |
| `approved` | Cleared. You can create the card | Call [Create a card](/platform/cards/create-a-card) |
| `needs_information` | More detail is needed to process the application | Supply the missing details and re-check |
| `needs_verification` | Selfie verification is still required for intermediate KYC | Send the customer to the `application_link` in the response, then re-check |
| `manual_review` | A reviewer is checking the application | Wait |
| `denied` | The application was rejected | Stop. The customer can't be issued a card |
| `locked` | The application is locked for a security concern | Contact support |
| `canceled` | The application was canceled | Start a new application if still needed |

When `application_status` is `needs_verification`, the response includes an `application_link`. Direct the customer there to finish their selfie verification, then poll again.

## Next step

Once `application_status` is `approved`, move on to [Create a card](/platform/cards/create-a-card).

