---
title: "Set a tier: start, renew, or upgrade its lease"
method: POST
path: "/tiers/v1/{tier}"
tags: ["Tiers"]
---

# Set a tier: start, renew, or upgrade its lease

`POST /tiers/v1/{tier}`

## Request

- Base URL: `https://api.run402.com`
- URL: `https://api.run402.com/tiers/v1/{tier}`
- Auth: one of:
  - API key in header `X-PAYMENT`
  - API key in header `SIGN-IN-WITH-X` and API key in header `Authorization`

Unified tier endpoint. The allowance settles first: send the ordinary SIGN-IN-WITH-X identity and, when the organization's allowance covers the price, the purchase settles from it with no 402, no payment header, and no wallet funds (response `paid_with: allowance`). An allowance that falls short gets a 402 whose `allowance` block names the allowance, price, and shortfall, with redeem-voucher and top-up next actions beside the x402/MPP challenge. Auto-detects start, renew, or upgrade (the `action` field; a start answers 201); downgrading during an active lease is rejected. Existing x402 behavior remains compatible. The explicit MPP Lightning charge path requires Run402-Payment-Profile: run402-mpp-lightning-charge-draft00-safety-v1, Accept-Payment selecting lightning/charge, exactly one supported principal credential, and one stable Idempotency-Key. It returns one fresh fixed-amount Bitcoin-mainnet BOLT11 invoice per emitted challenge, retains quote metadata, and requires exact-request reconciliation after possible dispatch.

## Path parameters

- `tier` 'prototype' | 'hobby' | 'team', required

## Headers

- `Run402-Payment-Profile` 'run402-mpp-lightning-charge-draft00-safety-v1'
- `Accept-Payment` string
- `Idempotency-Key` string

## Response `200`

Tier renewed or upgraded — OR, for `prototype` on an organization that already holds perpetual prototype, a short-circuit before the paywall (kygit-handoff D4/D5): no 402 challenge is answered, no payment is verified or settled, no ledger row is written. Paying twice is not charged twice.

- union
  - TierLease
    - `wallet` string
    - `action` 'start' | 'renew' | 'upgrade' | 'downgrade': What happened: start (a new lease, HTTP 201), renew (extend), upgrade (higher tier), or downgrade (lower tier, prorated refund)
    - `previous_tier` string, nullable: Previous tier (null on the first lease)
    - `tier` 'prototype' | 'hobby' | 'team'
    - `lease_started_at` string, date-time
    - `lease_expires_at` string, date-time, nullable: null for a perpetual tier (kygit-handoff D4 — prototype). Non-null once upgraded to a leased tier (hobby/team).
    - `payment_replay` boolean: True when this rail-qualified durable payment identity had already committed a tier outcome. The original action is preserved and no lease/refund/ledger effect runs again.
    - `funds_moved` boolean: Whether this HTTP attempt moved funds. False on an exact tier-payment replay.
    - `committed_lease_started_at` string, date-time: Lease start committed by the original payment outcome. Unlike the live lease view, this remains stable on replay.
    - `committed_lease_expires_at` string, date-time: Lease expiry committed by the original payment outcome. Unlike the live lease view, this remains stable on replay.
    - `paid_with` 'allowance' | 'x402' | 'mpp': What settled the purchase. `allowance` means the organization's allowance paid and nothing moved on-chain: the allowance rail settles ahead of the paywall for a SIWX-identified caller whose allowance covers the price, so no 402 was issued and no wallet funds were needed.
    - `allowance_used_usd_micros` integer: Allowance consumed by this purchase (0 unless paid_with is allowance).
    - `allowance_remaining_usd_micros` integer: The organization's allowance after this purchase.
  - MppLightningTierResult
    - `profile` 'run402-mpp-lightning-charge-draft00-safety-v1', required
    - `protocol` 'mpp', required
    - `method` 'lightning', required
    - `intent` 'charge', required
    - `intent_id` string, required
    - `attempt_id` string, required
    - `payment_hash` string, required
    - `amount_usd_micros` string
    - `payment_state` object, required
      - `raw_node_state` 'SETTLED', required
      - `terminality` 'terminal_paid', required
      - `settlement_role` 'primary', required
      - `invoice_amount_msat` string, required
      - `received_amount_msat` string, required
      - `excess_amount_msat` string, required
    - `fulfillment` object, required: Immutable committed tier result plus payment identity, ledger entry, protocol receipt, settlement attestation, and latest outcome attestation.
    - `current_status` object, required: Live organization tier status, kept distinct from the immutable fulfillment.
    - `credits` object[]
    - `payment_replay` boolean, required
    - `funds_moved` boolean, required
  - TierAlreadyActive: kygit-handoff D4/D5 — the perpetual-prototype re-purchase short-circuit. Mounted ahead of the x402 paywall: a POST /tiers/v1/prototype from an organization that already holds perpetual prototype answers this shape at 200 with no charge attempted, no payment verified or settled, and no ledger row written.
    - `status` 'already_active', required
    - `deduplicated` true, required
    - `tier` 'prototype', required
    - `lease` 'perpetual', required
    - `lease_days` null, nullable, required
    - `lease_expires_at` 'null', date-time, nullable, required
    - `active` true, required

## Other responses

- `201`: Lease started (`action: start`)
- `400`: Cannot downgrade during active lease
- `402`: Payment or SIWX authentication required. Existing routes return x402 discovery fields. On a priced route, when the caller was identified and its allowance was checked first, the body also carries `allowance: { allowance_usd_micros, price_usd_micros, shortfall_usd_micros }` and `redeem_voucher` / `top_up` next actions: the shortfall, not the whole price, is what a voucher or top-up must cover. An explicitly selected MPP Lightning tier request returns exactly one WWW-Authenticate: Payment challenge plus retained intent, attempt, quote, fixed invoice amount, and expiry metadata; the response is no-store.
- `409`: The retained Lightning intent is pending, in recovery, credited, or conflicts with the supplied request. No new actionable payment offer is returned. `IDEMPOTENCY_KEY_REUSED`: the Idempotency-Key already answered a different request. Nothing from the first response is returned; next action `new_idempotency_key`.
- `503`: Lightning quote, invoice issuance, node observation, or retained payment state is temporarily unavailable. Retry only the identical request as directed.

---

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