---
title: "Buy 30 days of a plan from the balance"
method: POST
path: "/v1/account/plan/balance"
tags: ["Plans"]
---

# Buy 30 days of a plan from the balance

`POST /v1/account/plan/balance`

## Request

- Base URL: `https://api.pmwallets.com`
- URL: `https://api.pmwallets.com/v1/account/plan/balance`
- Auth: API key in header `x-api-key`

CHARGES THE BALANCE the tier price for 30 days that never renew (starts now, or queues behind the running period). maxCents caps the charge (409 price_changed). requestId is required: a retry with it returns the same period, never a second charge. Refused while a card plan is active.

## Request body

- object
  - `tier` 'base' | 'pro' | 'max', required: Base 499, Pro 1499, Max 3999 cents per 30 days.
  - `maxCents` integer, required: Most you agree to be charged, in cents.
  - `requestId` string, required: Your idempotency key for this purchase; reuse it on retry, use a new one for a new purchase.

## Response `201`

Bought (HTTP 201); the body also carries the updated plan status.

- object
  - `outcome` 'started' | 'queued' | 'replayed'
  - `startsAt` string
  - `endsAt` string
  - `cents` integer
  - `tiers` PlanTier[]
    - `tier` 'base' | 'pro' | 'max'
    - `cents` integer: Monthly price.
    - `daily` integer: Paid-band address unlocks per UTC day.
    - `monthly` integer: Paid-band address unlocks per period.
    - `push` integer: Wallets followed without the hourly charge.
    - `exports` integer: Distinct wallets exported (full range) per period.
    - `rank` integer
    - `onSale` boolean
    - `trialDays` integer
  - `plan` object, nullable
    - `state` 'active' | 'grace'
    - `tier` string
    - `source` 'card' | 'balance'
    - `periodStart` string, nullable
    - `periodEnd` string
    - `endedAt` string
    - `graceUntil` string
    - `cancelAtPeriodEnd` boolean
    - `renewing` boolean
    - `nextTier` string, nullable
    - `queued` object, nullable
      - `tier` string
      - `startsAt` string
      - `endsAt` string
    - `failedPayment` boolean
    - `trialing` boolean
  - `balance` object
    - `cents` integer
    - `periodDays` integer
  - `baseTrial` object
    - `days` integer
    - `eligible` boolean
    - `refused` boolean
  - `usage` object
    - `daily` integer
    - `dailyUsed` integer
    - `monthly` integer
    - `monthlyUsed` integer
    - `push` object
      - `slots` integer
      - `used` integer
    - `exports` object
      - `cap` integer
      - `used` integer
    - `lookups` object
      - `cap` integer
      - `usedToday` integer
  - `trial` object

## Other responses

- `400`: Invalid parameter or body; `message` names what was expected.
- `401`: No valid API key (missing, malformed, unknown or revoked).
- `402`: `code: insufficient_balance`; nothing charged.
- `409`: `code` one of: price_changed (with `cents`), card_active, fix_payment, checkout_open, already_queued, request_conflict. Nothing charged.
- `503`: `code: stripe_unavailable` or temporarily unavailable; nothing charged.

---

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