# Request paid plan change

`POST https://api.instacloud.com/orgs/{orgId}/billing/plan-change`

**Token scope:** `account` · `org` — read-only tokens refused (not a GET).

Free → paid takes effect once paid; Pro → Team next UTC day after payment; downgrade at the current paid period end (owner/admin)

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgId` | path | `string` | yes |  |

## Request body (application/json)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `tier` | `"free" \| "pro" \| "team"` | yes |  |
| `idempotencyKey` | `string` | yes |  |
| `expectedFeeCents` | `integer` | no | Required for Pro/Team: amount due now accepted from the options response, excluding tax; zero for a scheduled downgrade. Omit for Free. |

## Response 200

Default Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes |  |
| `fromTier` | `string` | yes |  |
| `toTier` | `string` | yes |  |
| `status` | `"awaiting_payment" \| "scheduled" \| "applied" \| "failed" \| "cancelled"` | yes |  |
| `effectiveAt` | `string` | yes |  |
| `includedUsd` | `number` | yes |  |
| `changeKind` | `"upgrade" \| "downgrade"` | no |  |
| `renewalAt` | `string` | no |  |
| `cancellable` | `boolean` | no |  |
| `paymentUrl` | `string \| null` | no |  |

## Response 400

Default Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | `string` | yes |  |

## Response 403

Default Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | `string` | yes |  |

## Response 404

Default Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | `string` | yes |  |

## Response 409

Default Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | `string` | yes |  |

## Response 503

Default Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | `string` | yes |  |
