# Troubleshooting (/docs/troubleshooting)



Every error response is JSON with an `error` field.

## `401 unauthorized` [#401-unauthorized]

The bearer key is missing, malformed, revoked, or expired. Send
`Authorization: Bearer sk_viralquery_...` and never put the key in a URL or prompt.

## `402 subscription_required` [#402-subscription_required]

The key has no active subscription. Start monthly or annual checkout through
**[Get an API key](/docs/get-api-key)**.

## No workspace [#no-workspace]

Call `POST /v1/workspace` with a description, Apple App Store link, HTTPS website, or a combination
of those fields before writing rules or starting a scroll. The tenant owns one stable workspace,
but its research brief and subject are editable with `PUT /v1/workspace`. Re-posting a different
subject with `POST` returns `409 workspace_already_set`; use `PUT` for an intentional change.

## A scroll is already running [#a-scroll-is-already-running]

Only one scroll can be queued or running for the workspace. Poll `GET /v1/scrolls?id=...` until it
reaches `completed`, `failed`, or `cancelled`. A second create attempt returns
`409 scroll_active_limit`.

## Research capacity is at 100% [#research-capacity-is-at-100]

Call `GET /v1/usage` and inspect `usage.daily.usedPct`. Research uses a daily AI budget, not monthly
scroll slots, and the daily percentage resets at 00:00 UTC. Wait for the reset before starting more
research; reads remain bounded and do not consume the AI budget.

## `429 rate_limited` [#429-rate_limited]

The request-rate guard rejected a burst of calls. Honor the `Retry-After` response header, wait that
many seconds, and retry with backoff. Do not translate this error into a scroll count.

## Trends say `insufficient_history` [#trends-say-insufficient_history]

This is expected until the workspace has at least two completed scrolls. ViralQuery does not invent
a trend from one observation.

## Subscription claim returns `pending` [#subscription-claim-returns-pending]

Finish Stripe checkout, then poll `POST /v1/subscribe/claim` with the same `claimToken`.
`already_claimed` means the key was already shown once; use the email recovery flow to rotate it.
