---
title: "List Plans"
method: GET
path: "/v1/plans"
tags: ["Billing Plans"]
---

# List Plans

`GET /v1/plans`

## Request

- Base URL: `https://api.xdata.kr` (the document declares no server; this is the origin it was published from)
- URL: `https://api.xdata.kr/v1/plans`
- Auth: one of:
  - HTTP basic
  - OAuth 2 (authorization code, authorization URL `https://api.xdata.kr/oauth/authorize`, token URL `https://api.xdata.kr/oauth/token`)

요금제 목록 조회.

## Query parameters

- `query` PlanListQuery, required: 요금제 목록 조회 쿼리. `env_scope`는 요청 헤더 `X-Env-Scope`에서 라우트 의존성으로 주입되므로 쿼리에 없다. `deleted_at IS NULL` 필터는 서비스 레이어가 항상 적용한다(쿼리 미노출).
  - `status` string[], nullable: 상태 필터. 미지정 시 ACTIVE+DEPRECATED 기본(노출 가능 행).
  - `tier` 'FREE' | 'PAID', nullable: 등급 필터.
  - `limit` integer: 페이지 크기. 1~100. 기본 20.
  - `cursor` string, nullable: 이전 응답의 next_cursor.
- `env_scope` 'production' | 'real_test' | 'sandbox', nullable: 환경을 고릅니다. 값은 production · real_test · sandbox 중 하나입니다. 경로 접두(/v1/sandbox/... · /v1/test/... · /v1/production/...) · X-Env-Scope 헤더 · env_scope 쿼리 가운데 한 통로로 반드시 보내야 합니다. 빼면 자동으로 채우지 않고 거절하며, 두 통로에 서로 다른 값을 담아도 거절합니다. 거절은 HTTP 422 이고 오류 코드는 VALIDATION_ENV_SCOPE_MISMATCH 입니다.

## Headers

- `Authorization` string, nullable
- `X-Env-Scope` 'production' | 'real_test' | 'sandbox', nullable: 환경을 고릅니다. 값은 production · real_test · sandbox 중 하나입니다. 경로 접두(/v1/sandbox/... · /v1/test/... · /v1/production/...) · X-Env-Scope 헤더 · env_scope 쿼리 가운데 한 통로로 반드시 보내야 합니다. 빼면 자동으로 채우지 않고 거절하며, 두 통로에 서로 다른 값을 담아도 거절합니다. 거절은 HTTP 422 이고 오류 코드는 VALIDATION_ENV_SCOPE_MISMATCH 입니다.

## Response `200`

Successful Response

- PageEnvelopePlanResponse
  - `items` PlanResponse[]: Page result items. Empty list allowed.
    - `plan_id` integer, required: plans.id (BIGSERIAL PK).
    - `code` string, required: 비즈 식별 코드. 환경 내 유니크 (SCHEMA uq_plans_code_env_active).
    - `name` string, required: 사용자 노출 명칭.
    - `description` string, nullable: 요금제 설명 (마크다운 허용).
    - `tier` 'FREE' | 'PAID', required: 요금제 등급. FREE/PAID.
    - `billing_cycle` 'ONCE' | 'MONTHLY' | 'YEARLY', required: 청구 주기. ONCE/MONTHLY/YEARLY.
    - `price` MoneyMinor, required: minor unit 정수 기반 금액 객체. SCHEMA 컬럼 `price_amount_minor BIGINT NOT NULL CHECK (>= 0)` + `currency CHAR(3) DEFAULT 'KRW'` + `tax_included BOOLEAN DEFAULT TRUE`를 API 응답의 nested `price` 객체로 묶는다. - `amount_minor`: 1회 청구/결제 금액의 minor unit 정수(KRW는 원 단위, JPY는 엔 단위). 절대 float/Decimal 사용 금지(부동소수 오차 + JSON 직렬화 일관성). - `currency`: v1 단일 KRW. 통화 확장은 별도 ADR. - `tax_included`: 부가세 포함 여부. NULL 금지(SCHEMA NOT NULL DEFAULT TRUE 정합).
      - `amount_minor` integer, required: minor unit 정수 금액. KRW는 원 단위. 음수 금지 (SCHEMA CHECK 정합).
      - `currency` 'KRW', required: 통화 코드 (v1=KRW). 세 글자여야 한다.
      - `tax_included` boolean, required: 부가세 포함 여부. SCHEMA NOT NULL.
    - `status` 'DRAFT' | 'ACTIVE' | 'DEPRECATED' | 'RETIRED', required: 요금제 상태.
    - `env_scope` 'sandbox' | 'real_test' | 'production', required: 환경 스코프.
    - `created_at` string, date-time, required: 발행 시각 (TIMESTAMPTZ, ISO 8601 + offset 포함; naive 입력 시 422).
    - `addon_select_min` integer, nullable: W6/G7: min Path B pack count at subscribe (NULL=unlimited).
    - `addon_select_max` integer, nullable: W6/G7: max Path B pack count (NULL=unlimited).
    - `audience` 'standard' | 'integrator': 기본값 standard · 연동사 요금제는 integrator.
    - `max_active_account_links` integer, nullable: 연동사 요금제의 좌석 상한 - 한 desktop_agent 클라이언트가 가질 수 있는 ACTIVE account_links 최대 수. audience='integrator' 일 때만 뜻이 있고 NULL 은 제한 없음(또는 해당 없음)이다.
    - `included_usage_free_units` integer, nullable: 요금제 전체의 종량 무료 허용량(한 청구 기간 기준) - (sum of all data_provider/action usage_records quantity, not per action). NULL or 0 = no free allowance (billed from unit 1, current behavior).
    - `daily_token_limit` integer, nullable: T12: daily usage-token allowance this plan grants, read from the linked quota_policies row (plans.quota_policy_id). The unit is usage tokens, not call count. null means THIS PLAN HAS NO DAILY CAP from a quota policy - do not read it as not-configured-yet. It covers four cases that are deliberately not distinguished: no policy linked, a linked policy whose own daily_limit is null, a linked policy that was soft-deleted, and the admin create/update responses (those are built from RETURNING, which this repository keeps narrow - read the plan again to get the limits).
    - `monthly_token_limit` integer, nullable: T12: monthly usage-token allowance from the same quota_policies row. NULL = no monthly limit for this plan (the user instruction gives a monthly number for the paid plans only). The unit is usage tokens.
    - `contact_sales` boolean: 상담으로 가입하는 요금제(엔터프라이즈)이면 true. 고객이 스스로 가입하는 길(0원 가입 · 결제 가입)에 서지 않는다. 입력값을 받지 않고 `code` 에서 유도한다(`CONTACT_SALES_PLAN_CODES`).
  - `next_cursor` string, nullable: Opaque cursor for next page, or null on last page.
  - `has_more` boolean: Whether another page exists. False when next_cursor is null.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/xdata/apis/xboss-api.md) · [All operations](https://skmtc.dev/xdata/apis/xboss-api/llms.txt) · [OpenAPI document](https://skmtc.dev/xdata/apis/xboss-api/revisions/816de78950db?raw)
