Skip to content

Error codes

All errors share a consistent JSON envelope:

{
"error": {
"code": "INVALID_API_KEY",
"message": "API key is invalid or no longer recognized.",
"param": null,
"request_id": "req_01J..."
}
}

request_id is also echoed in the response headers — please quote it in support tickets.

CodeHTTPMeaning
MISSING_AUTH401No Authorization header sent.
INVALID_API_KEY401Key not found.
REVOKED_API_KEY401Key was revoked.
WRONG_AUTH_TYPE401Sent an API key to a dashboard endpoint, or a Clerk JWT to a product endpoint.
INVALID_CLERK_TOKEN401JWT failed signature, expiry, or issuer checks.
ACCOUNT_NOT_FOUND404Clerk user has no Nordva Launch account. Call POST /v1/auth/provision.
CodeHTTPMeaning
VALIDATION_ERROR400Body or query fails schema. param names the offending field.
INVALID_PLAN400Plan name not recognised (must be indie or builder).
RATE_LIMITED429Plan rate limit exceeded. Retry-After header included.
PLAN_LIMIT_REACHED403Monthly quota exhausted. Upgrade or wait for the cycle to reset.
PLAN_UPGRADE_REQUIRED403Feature gated to a higher plan.
NOT_FOUND404Resource missing or owned by another project.
CANNOT_EDIT_PUBLISHED409Tried to edit a published changelog entry.
HOSTNAME_ALREADY_REGISTERED409Custom hostname already registered to another project.
IDEMPOTENCY_CONFLICT409Same Idempotency-Key used with a different request body.
CodeHTTPMeaning
BILLING_NOT_CONFIGURED503Server-side Paddle environment is not configured.
NO_BILLING_ACCOUNT404Account has no Paddle customer yet — must complete a checkout first.
BILLING_PORTAL_UNAVAILABLE502Paddle portal-session API call failed. Retry shortly.
CodeHTTPMeaning
CUSTOM_DOMAIN_NOT_CONFIGURED503Server-side Cloudflare for SaaS env not configured.
CUSTOM_DOMAIN_LIMIT_REACHED403Reached the per-plan custom hostname limit.
CodeHTTPMeaning
KEY_INSUFFICIENT_PERMISSIONS403A publishable key (nv_pub_*) was used on a secret-only endpoint. Publishable keys are browser-safe and may only write to the public endpoints listed in Authentication — list, read, delete, and admin operations require a secret key (nv_live_* / nv_test_*).
API_KEY_LIMIT_REACHED422Project already has the per-plan maximum of active keys of the requested type. Secret and publishable keys are counted independently. Revoke an unused key of the same type, or upgrade the plan.
CodeStatusMeaning
INVALID_SLUG422Slug is not 1–40 lowercase letters, numbers and hyphens.
SLUG_TAKEN409The slug is in use, reserved, or was released by another project in the last 30 days.
PROJECT_LIMIT_REACHED403Dashboard only. The account already has as many projects as its plan includes (Free 2, Indie 4, Builder 10).
LAST_PROJECT409Dashboard only. An account keeps at least one project, so its only project cannot be deleted.
PROJECT_NOT_FOUND404Dashboard only. The project named in X-Nordva-Project, or chosen when approving a CLI sign-in, is not one of this account’s.
SLUG_CHANGE_LIMIT_REACHED429The slug was already changed twice in the last 30 days. A project’s first rename, away from the generated slug, is not counted. remediation gives the date it can change again. Old links keep working in the meantime.
CodeStatusMeaning
STRIPE_NOT_CONNECTED409No Stripe account is connected to this project. Connect one in the dashboard.
STRIPE_ALREADY_CONNECTED409Disconnect the current key before connecting another.
STRIPE_KEY_NOT_RESTRICTED422The key is not a restricted key (rk_live_ / rk_test_). If a secret key was pasted, roll it in Stripe.
STRIPE_KEY_INVALID422Stripe did not recognise the key.
STRIPE_KEY_MISSING_PERMISSION422A required read permission is missing. remediation carries Stripe’s message naming it.
STRIPE_CONNECTION_LIMIT_REACHED403Indie includes one Stripe connection per account; Builder one per project.
STRIPE_CONNECT_NOT_CONFIGURED503Server-side encryption key for Stripe connections is not configured.
CONTACT_NOT_FOUND404No contact with that id in this project.
EMAIL_TEMPLATE_INVALID422Unknown placeholder, missing required placeholder, or empty/too long subject or body. param is subject or body.
CodeHTTPMeaning
INTERNAL_ERROR500Unexpected server error. Include the request_id in your report.
TURNSTILE_FAILED400Cloudflare Turnstile token verification failed.

If you hit a code not listed here, please open an issue — we keep the canonical list at packages/api/src/lib/errors.ts.