---
title: "Create a tier (admin)"
method: POST
path: "/admin/tiers"
tags: ["admin"]
---

# Create a tier (admin)

`POST /admin/tiers`

## Request

- Base URL: `https://api.qualityclouds.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.qualityclouds.ai/admin/tiers`
- Auth: one of:
  - HTTP bearer
  - OpenID Connect (`https://account.qualityclouds.com//realms/ai-production/.well-known/openid-configuration`)

Adds a tier to the catalogue. The tier is created retired: configure its quotas, then activate it. Requires the Keycloak 'admins' group.

## Request body

- AdminTierCreateRequest: POST /admin/tiers — add a tier to the catalogue. The tier is created **retired**: it becomes visible for sale only after its quotas are configured and it is activated (QSA-1624). There is deliberately no ``is_active`` field here.
  - `code` string, required: Immutable catalogue key, lower snake case, up to 20 characters (for example 'solo_developer').
  - `name` string, required: Display name shown to customers.
  - `description` string: Customer-facing description.
  - `rank` integer, required: Commercial order, unique across tiers. Leave gaps so a tier can be inserted later (the seeded ranks are 0, 10, 20, 30, 100).
  - `price_amount` integer, nullable: Price in the currency's minor unit (pence, cents).
  - `currency` string, nullable: ISO currency code, for example 'GBP'.
  - `max_users` integer, nullable: Seat cap. Null means unlimited.
  - `is_billable` boolean: Whether the tier can be bought through self-service checkout. Requires both Stripe identifiers.
  - `stripe_price_id` string, nullable: Stripe price id, created in the Stripe dashboard beforehand.
  - `stripe_product_id` string, nullable: Stripe product id, created in the Stripe dashboard beforehand.

## Response `201`

Successful Response

- AdminTierResponse: One tier as an administrator sees it. Unlike the public ``TierResponse`` on GET /api/v1/tiers, this carries the Stripe identifiers and the organisation count. It is served only behind the system-admin guard.
  - `code` string, required
  - `name` string, required
  - `description` string, required
  - `rank` integer, required
  - `is_billable` boolean, required
  - `is_active` boolean, required
  - `price_amount` integer, nullable, required
  - `currency` string, nullable, required
  - `max_users` integer, nullable, required
  - `stripe_price_id` string, nullable, required
  - `stripe_product_id` string, nullable, required
  - `organisations_count` integer, required
  - `quotas` AdminTierQuotaResponse[], required
    - `quota_key` string, required
    - `max_allowed` integer, required
    - `reset_period` string, nullable, required
  - `tools` AdminTierToolResponse[], required
    - `tool_id` string, required
    - `included` boolean, required

## Other responses

- `401`: Unauthorized
- `403`: Forbidden
- `422`: Validation Error

---

[API](https://skmtc.dev/qualityclouds/apis/qai-orchestrator-api.md) · [All operations](https://skmtc.dev/qualityclouds/apis/qai-orchestrator-api/llms.txt) · [OpenAPI document](https://skmtc.dev/qualityclouds/apis/qai-orchestrator-api/revisions/250c849925af?raw)
