> ## Documentation Index
> Fetch the complete documentation index at: https://docs.macropay.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Seat-Based Pricing

> Sell to teams with assignable seats, volume tiers, and per-seat benefit grants — tax handled as Merchant of Record.

When you sell to a team, one person pays and several people use the product. Seat-based pricing models exactly that: a billing manager buys a quantity of seats, then hands each one to a teammate by email or customer ID. Benefits unlock per person, the moment a seat is claimed — not at purchase.

Because Macropay is the **Merchant of Record**, the price your billing manager sees already accounts for global sales tax and VAT. We're the seller on record, we remit the tax in every jurisdiction, and your team only deals with one clean per-seat number.

<Info>
  **Reach for seat-based pricing when you're selling:**

  * A team subscription where one admin pays for the whole group
  * A perpetual team license bought once, owned forever
  * An organization-wide license priced per head
  * Anything with volume breaks — e.g. \$12/seat up to 9 seats, \$10/seat at 10+
</Info>

<Warning>
  Seat-based pricing is in **private beta**. Reach out to support to switch it on for your organization.
</Warning>

## The seat lifecycle

A seat moves through three states. Knowing them is enough to reason about everything else on this page:

| State       | What it means                                          | Benefits        |
| ----------- | ------------------------------------------------------ | --------------- |
| **Pending** | Assigned and invited, waiting on the teammate to claim | Not yet granted |
| **Claimed** | Teammate accepted; the seat is theirs                  | Granted         |
| **Revoked** | Pulled back; the seat is free to reassign              | Removed         |

The flow a billing manager runs through:

1. **Buy** a product — subscription or one-time — with a seat count.
2. **Assign** seats to teammates by email, your external customer ID, or an existing Macropay customer ID.
3. **Invite** — each teammate gets a claim link (valid for 24 hours).
4. **Claim** — once accepted, benefits switch on automatically for that person.
5. **Adjust** over time: revoke and reassign, resend expired invites, or scale up.

## Subscription vs. one-time

Both purchase types support seats. The difference is how long a claimed seat lasts and how you add more.

|                    | Subscription                     | One-time                  |
| ------------------ | -------------------------------- | ------------------------- |
| **Payment**        | Recurring (monthly / yearly)     | Single charge             |
| **Seat lifespan**  | Active while the subscription is | Perpetual — never expires |
| **Adding seats**   | Modify the subscription          | Place a new order         |
| **Benefit window** | While the subscription is active | Forever, once claimed     |

<Tip>
  Recurring team access → **subscription**. A team license your customer buys outright and keeps → **one-time**.
</Tip>

## How volume tiers price out

Seat pricing is **volume-based**: the total seat count selects one tier, and that tier's rate applies to *every* seat — not a graduated blend. Cross a threshold and the whole order reprices.

Say you sell a "Design Studio" plan with these monthly tiers:

| Seats | Price per seat |
| ----- | -------------- |
| 1–4   | \$12           |
| 5–9   | \$10           |
| 10+   | \$8            |

An agency buying **6 seats** lands in the 5–9 tier, so all six bill at \$10 → **\$60/month**. Add a seventh teammate and they're still in-tier at \$70/month. Grow to **10 seats** and every seat drops to \$8 → **\$80/month** instead of the \$90 they'd pay at the lower tier's rate.

## Create a seat-based product

<Steps>
  <Step title="Start a new product">
    In your [dashboard](https://app.macropay.ai), open **Products** and click **Create Product**.
  </Step>

  <Step title="Fill in the basics">
    Name, description, and media — same as any other product.
  </Step>

  <Step title="Choose seat-based pricing">
    Under **Pricing**, set:

    * **Product type** — Subscription or One-time
    * **Billing cycle** (subscriptions only) — Monthly or Yearly
    * **Pricing type** — Seat-based
  </Step>

  <Step title="Define your tiers">
    * **Min seats** — the smallest quantity someone can buy
    * **Tiers** — for each one, set a **Max seats** (leave blank for the top, open-ended tier) and a **Price per seat** in cents

    The total seats purchased picks the tier; that rate then applies to all seats (see the volume example above).
  </Step>

  <Step title="Attach benefits">
    Pick the benefits seat holders receive — license keys, file downloads, GitHub or Discord access, and so on. These fire on **claim**, never at purchase.
  </Step>
</Steps>

<Info>
  A seat-based product **grants nothing to the billing manager by default** — benefits go only to people who claim a seat. If the manager also wants access, they assign a seat to themselves, and it counts toward the purchased total.
</Info>

## Manage seats from code

Billing managers can assign and manage seats in the **Customer Portal**, but everything is also available over the API — handy for provisioning seats straight from your own admin panel or onboarding flow.

### Assign a seat

`POST /v1/customer-seats` invites a teammate and creates a **pending** seat. A claim link goes out by email automatically.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.macropay.ai/v1/customer-seats \
    -H "Authorization: Bearer $MACROPAY_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "subscription_id": "sub_8Qk2c1Lm",
      "email": "priya@northwind.studio"
    }'
  ```

  ```python Python theme={null}
  from macropay_sdk import Macropay

  with Macropay(access_token="<YOUR_BEARER_TOKEN_HERE>") as macropay:
      seat = macropay.customer_seats.assign_seat(request={
          "subscription_id": "sub_8Qk2c1Lm",
          "email": "priya@northwind.studio",
      })
      print(seat.status)  # "pending"
  ```

  ```typescript TypeScript theme={null}
  import { Macropay } from "@macropay/sdk";

  const macropay = new Macropay({ accessToken: process.env.MACROPAY_TOKEN });

  const seat = await macropay.customerSeats.assignSeat({
    subscriptionId: "sub_8Qk2c1Lm",
    email: "priya@northwind.studio",
  });

  console.log(seat.status); // "pending"
  ```
</CodeGroup>

### List, resend, and revoke

```bash theme={null}
# See every seat on a subscription and its status
curl https://api.macropay.ai/v1/customer-seats \
  -H "Authorization: Bearer $MACROPAY_TOKEN"

# Resend an invite when the 24-hour link has expired
curl -X POST https://api.macropay.ai/v1/customer-seats/seat_3Rt9p/resend \
  -H "Authorization: Bearer $MACROPAY_TOKEN"

# Revoke a seat — benefits are removed, the seat frees up for reassignment
curl -X DELETE https://api.macropay.ai/v1/customer-seats/seat_3Rt9p \
  -H "Authorization: Bearer $MACROPAY_TOKEN"
```

<Warning>
  Revoking a seat does **not** trigger a refund. The subscription keeps billing for its full seat count until the manager changes the quantity.
</Warning>

### React to seat events with webhooks

Subscribe to seat webhooks to keep your own systems in lockstep — provision access on claim, reclaim a license on revoke:

| Event                    | Fires when                                  |
| ------------------------ | ------------------------------------------- |
| `customer_seat.assigned` | A seat is created and the invite is sent    |
| `customer_seat.claimed`  | A teammate accepts and benefits are granted |
| `customer_seat.revoked`  | A seat is pulled back and benefits removed  |

## Good to know

* Seats are assigned one at a time in the dashboard — for bulk provisioning, loop the [assign endpoint](/api-reference/customer-seats/assign).
* Claim links expire 24 hours after they're sent; resend to refresh.
* The billing manager gets no benefits unless they claim a seat of their own.
* Up to **1,000 seats** per subscription.
* Per-seat metadata is capped at **10 keys** and **1 KB** total.

## Next steps

Ready to wire it up end to end — assignment, claim flow, webhook handling, and full code samples? See the [seat-based pricing implementation guide](/guides/seat-based-pricing).
