---
title: "Read a user's plan history"
method: GET
path: "/v1/admin/users/{user_id}/plan"
tags: ["Admin"]
---

# Read a user's plan history

`GET /v1/admin/users/{user_id}/plan`

## Request

- Base URL: `https://api.naturali.ai`
- URL: `https://api.naturali.ai/v1/admin/users/{user_id}/plan`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://api.naturali.ai/authorize`, token URL `https://api.naturali.ai/token`, scopes: `mcp:access`)

A cursor page of the account's plan history, newest first, and the rung it is on now. Needs the `admin` role.
The history is append-only, so this is the record of who put the account where and why — nothing edits or removes a line. `plan` at the top level is the same value every entitlement check resolves, so one response answers both "what plan is this?" and "how did it get there?".

## Path parameters

- `user_id` string, required

## Query parameters

- `limit` integer
- `cursor` string

## Response `200`

A page of the plan history.

- PlanEventPage
  - `data` PlanEvent[], required
    - `id` string, required: Public plan-history line ID (sev_ prefix).
    - `plan` 'free' | 'pro' | 'business' | 'enterprise', required: The rung the account was put on by this line.
    - `retention_days` integer, nullable, required: The contract window recorded with this line, in days. `null` on every rung whose window the plan itself sets, and on a contract that keeps content indefinitely — `plan` is what tells the two apart.
    - `reason` string, nullable, required
    - `recorded_by_user_id` string, nullable, required: The operator who recorded it. Null for a line no person wrote.
    - `created_at` string, date-time, required: When the rung took effect.
  - `plan` 'free' | 'pro' | 'business' | 'enterprise', required: The rung in effect: the highest held this month, or `free` when the account has no history.
  - `next_plan` 'free' | 'pro' | 'business' | 'enterprise', required: The newest line: the rung the account moves to when the month turns.
  - `next_cursor` string, nullable, required: Pass as `cursor` for the next page; null on the last page.

## Other responses

- `400`: The request was malformed or failed validation.
- `401`: Missing or invalid credentials.
- `403`: The caller does not hold the `admin` role.
- `404`: No such user.

---

[API](https://skmtc.dev/naturali/apis/naturali-ai-api.md) · [All operations](https://skmtc.dev/naturali/apis/naturali-ai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/naturali/apis/naturali-ai-api/revisions/e4905b78f422?raw)
