> ## Documentation Index
> Fetch the complete documentation index at: https://docs.insito.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Plan limits

> What counts against your monthly response cap, what doesn't, and how Insito communicates plan exhaustion.

Insito's pricing is **response-based**. Each paid plan sets a monthly response
cap that is enforced **per app (project)**, not across your whole organisation.
Triggers, impressions, and "no survey shown" returns are free.

## What counts

A response counts the first time a row is written to the `responses` table for
an app in the current calendar month. That happens when:

* A user submits a complete response from the modal
  (`MicroSurvey.submitResponse(...)`).
* A **partial/autosave** response is first persisted (`POST /v1/sdk/responses`).
  Later autosave updates to the same response don't count again.
* A queued offline response is flushed and accepted by the server.

## What doesn't count

* `MicroSurvey.trigger()` / `evaluate` calls that return `survey: null`.
* Impressions (`/v1/sdk/impression` — recorded for throttling and show caps).
* Responses rejected with a 4xx (e.g. validation failures).

## Plans

| Plan    | Monthly responses | Apps included | Price   |
| ------- | ----------------- | ------------- | ------- |
| Free    | 250               | 1             | €0      |
| Starter | 2,000 per app     | 1             | €29/mo  |
| Growth  | Unlimited per app | 1             | €79/mo  |
| Studio  | Unlimited per app | 3             | €199/mo |

<Note>
  Response caps are **per app**. Paid plans (Starter, Growth, Studio) can
  purchase additional apps as an add-on, which increases the number of apps
  included in the subscription. Limits reset on the first day of each calendar
  month at UTC midnight.
</Note>

## What happens at the limit

When an app reaches its monthly cap, enforcement is immediate — there's no
end-of-day grace:

<Steps>
  <Step title="80% usage">
    Organisation owners receive an email warning that the app is approaching its
    monthly response cap. No user-visible change.
  </Step>

  <Step title="100% usage">
    `POST /v1/sdk/response` returns **`402`** with
    `{ "error": "response_limit_reached", "upgradeUrl": "...", "projectId": "..." }`.
    The SDK's `response_failed` event fires with `reason: "response_limit_reached"`,
    and the response is **not** queued for retry.
  </Step>

  <Step title="Recovery">
    Upgrade the plan (or add an app) from
    [app.insito.io/settings/billing](https://app.insito.io/settings/billing), or
    wait for the monthly reset. New responses are accepted immediately after
    either.
  </Step>
</Steps>

## SDK behaviour when exhausted

When an app is over its cap, `MicroSurvey.trigger()` still works (triggers are
free) and the modal can still be shown. But `submitResponse` fails with an error
state. Because a re-submit would only re-fail, the response **isn't queued** —
the user returns to `idle` and the host app's `response_failed` listener fires
with `reason: "response_limit_reached"`.

## Querying current usage

Organisation-wide aggregate:

```bash theme={null}
curl -s https://api.insito.app/v1/dashboard/organization/usage \
  -H "Authorization: Bearer $JWT"
```

```json theme={null}
{
  "usage": {
    "plan": "growth",
    "year": 2026,
    "month": 5,
    "responseCount": 2347,
    "responseLimit": 2000,
    "percent": 100
  }
}
```

Per-app usage (the value the SDK cap is checked against):

```bash theme={null}
curl -s https://api.insito.app/v1/dashboard/projects/<projectId>/usage \
  -H "Authorization: Bearer $JWT"
```

See the dashboard's [Plan page](/dashboard/billing) for the human-friendly view.
