Activate feature

Activate cards for a verified customer, which creates their card application. Always send your business's card account.

Once the customer's KYC is complete, you can activate the card feature, virtual_cards, for them. Activation creates the customer's card application. First, check what is still missing with Check feature eligibility.

A money example. Ada earns about 24,000 USD a year and expects to spend 300 USD a month on her card. You send annual_remuneration 24000, estimated_monthly_limit 300 and your business's card account. If Gravv issues a card during activation, its daily limit is 300 USD.

Activate a feature

Use the Activate a feature endpoint to enable a feature for a customer. The request needs customer_id, feature_id and, for virtual_cards, the provider_data below:

curl --request POST \
     --url https://api.gravv.xyz/v1/risk/features/activate \
     --header 'Api-Key: <API_KEY>' \
     --header 'Idempotency-Key: 6e0d5427-399b-418e-a43f-12cffc8dd9c2' \
     --header 'Content-Type: application/json' \
     --data '
{
  "customer_id": "5b0f6c1e-2a8f-4c39-9d0e-0c7e3b9a1f42",
  "feature_id": "virtual_cards",
  "provider_data": {
    "annual_remuneration": 24000,
    "estimated_monthly_limit": 300,
    "account_id": "9b40be8d-9d74-4d2a-8897-dea3ef80ad23"
  }
}
'

When activation succeeds, the response has status active:

{
  "data": {
    "activated_at": "2026-10-13T11:20:05Z",
    "customer_id": "5b0f6c1e-2a8f-4c39-9d0e-0c7e3b9a1f42",
    "feature_id": "virtual_cards",
    "status": "active"
  },
  "error": null
}

Cards start here. Activating virtual_cards is how you create a card application. active means the application was submitted. It does not mean a card was issued, and the response carries no application id. Find the application with List card applications, track it until its application_status is approved, then create the card. See Create a card application.

If the customer already has an activation, the API returns it unchanged with message Feature activation already exists with status: <status>.

Provider data requirements

The provider_data object carries the feature-specific data that activation needs. Activating virtual_cards requires:

Field Type Required Description
annual_remuneration number yes Customer's expected annual inflow in USD. A JSON number of at least 1000
estimated_monthly_limit number yes Expected monthly card spend in USD. A JSON number of at least 1. When Gravv issues a card during activation, it also becomes that card's daily limit
account_id string always send it The id of your business's card account (type card, status active). The same card account backs every cardholder. See Set up your card account. Leaving it out fails with cards service: internal server error

Gravv fills in ip_address from the address your request comes from, and replaces any value you send. For a call from your server, that is your server's address.

Every error from this endpoint is HTTP 400 with a message in error, for example cards service: annual_remuneration must be a number of at least 1000, or failed to check liveness requirement: customer KYC must be completed before activating cards feature.

Liveness check requirement

When you activate virtual_cards, Gravv checks whether the customer completed a liveness check. A customer verified through document upload has no liveness check, so activation can't finish yet. The response has status pending_liveness and includes a websdk_url:

{
  "data": {
    "activated_at": "",
    "customer_id": "5b0f6c1e-2a8f-4c39-9d0e-0c7e3b9a1f42",
    "feature_id": "virtual_cards",
    "message": "Liveness verification required. Please complete the verification using the provided WebSDK URL.",
    "status": "pending_liveness",
    "websdk_url": "https://<verification-host>/websdk/p/…"
  },
  "error": null
}

Nothing is stored for this response. Send the customer to the websdk_url, which is valid for 30 minutes, to finish their liveness check. Then call Activate feature again with a new Idempotency-Key. If you send the same key, the API returns the stored pending_liveness response instead of activating.

Was this page helpful?