plan_required
The endpoint you called requires a higher plan than your current one.
HTTP 402 · Payment Required
Example response
{
"error": {
"code": "plan_required",
"message": "Batch validation requires a Pro or Business plan."
},
"meta": {
"request_id": "a1b2c3d4-...",
"latency_ms": 0
}
}What happened
The endpoint is gated to a higher plan. POST /v1/validate/batch requires Pro or Business. POST /v1/decide requires Business.
How to fix
- Check your current plan in the dashboard.
- Upgrade to the required plan, or
- During development, use a
vtv_test_key. Test keys bypass all plan gates and have unlimited quota.
Plan-gate matrix
The vatverify endpoint set is layered by plan. As of the current API version:
- Free / Starter / Pro / Business:
/v1/validate(single VAT lookup),/v1/rates, all read endpoints. - Pro / Business only:
/v1/validate/batch(batch VAT validation up to 50 numbers per request), webhooks. - Business only:
/v1/decide(tax-rules engine), BZSt qualified confirmation, audit log replay beyond 30 days.
Hitting plan_required always points at the same fix path: either upgrade, or swap the live key for a test key while you build the integration.
Why test keys bypass plan gates
Test mode is intentionally permissive. The contract: test-mode keys (prefix vtv_test_) return deterministic synthetic data, never hit live registries, and never count against quota or plan limits. The point is to let developers build and CI-test against the full API surface without upgrading first.
A practical consequence: a test integration that works fine in CI will hit plan_required the moment it is switched to a live key on a lower plan. The right place to gate-test plan restrictions is in staging with a live key on the actual deployed plan.
Common mistakes
- Calling
/v1/validate/batchon a Free or Starter plan: batch requires Pro+. - Calling
/v1/decideon a Pro plan: decide requires Business. - Expecting test keys to reflect plan restrictions: they do not. Use a live key to test plan gating.
Related errors
unauthorized: key is missing or invalid entirelyrate_limited: key is valid but quota is exhaustedwebhook_limit_reached: webhook slots full