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

# Products & pricing

> Create products, attach price variants, and publish — covering the draft → active lifecycle and every billing type from one-time to pay-what-you-want.

**A product is the listing; a price variant is how it's priced and billed — and a product needs at least one price variant before it can go live.** Get the creation order right and the rest is a small, predictable set of fields.

You can hand all of this to the agent — "create a $49 course, monthly option at $19, and a 3-payment plan" — and Crevio builds the product and its price variants for you. The model below is what those tools operate on, and what your own integrations will use directly.

## The product lifecycle

A product moves through three states via its `status` field:

| Status     | Meaning                                                                        |
| ---------- | ------------------------------------------------------------------------------ |
| `draft`    | Created but not visible or purchasable. The starting state.                    |
| `active`   | Published and available for purchase. Requires **at least one price variant**. |
| `archived` | Retired — no longer listed or purchasable, but kept for history.               |

<Warning>
  **You cannot publish in one call.** Creating a product with `status: "active"` and no price variants returns `422 validation_failed`. The required sequence is:

  1. `POST /products` → creates a **draft**.
  2. `POST /price_variants` (one or more) → attach pricing via `product: "prod_..."`.
  3. `PATCH /products/{id}` with `status: "active"` → publish.
</Warning>

### Step 1 — Create the draft product

```bash theme={null}
curl -X POST https://api.crevio.co/v1/products \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "The Complete Guitar Course",
    "description": "Go from zero to playing real songs.",
    "slug": "complete-guitar-course"
  }'
```

The response is a product with `"status": "draft"` and an `id` like `prod_abc123`. Other fields you can set at creation: `body_html`, `button_cta`, `available_from` / `available_until` (date-times for scheduled availability), `tax_code`, and `images` (covered below).

### Step 2 — Attach a price variant

Every price variant **must** reference its product:

```bash theme={null}
curl -X POST https://api.crevio.co/v1/price_variants \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "product": "prod_abc123",
    "name": "Full course",
    "amount_type": "fixed",
    "billing_type": "one_time",
    "amount": 9900,
    "currency": "usd"
  }'
```

### Step 3 — Publish

```bash theme={null}
curl -X PATCH https://api.crevio.co/v1/products/prod_abc123 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "status": "active" }'
```

<Tip>
  With the [`@crevio/sdk`](/developer/guides/api-overview#available-sdks) the same flow reads naturally:

  ```typescript theme={null}
  const product = await crevio.products.create({
    name: "The Complete Guitar Course",
    slug: "complete-guitar-course",
  });

  await crevio.priceVariants.create({
    product: product.id,
    name: "Full course",
    amount_type: "fixed",
    billing_type: "one_time",
    amount: 9900,
    currency: "usd",
  });

  await crevio.products.update({ id: product.id, status: "active" });
  ```
</Tip>

## The price variant model

A single product can carry several price variants (a "monthly" and an "annual", say), and each is defined by two key enums plus a handful of modifiers.

### `amount_type` — what the buyer pays

| Value    | Behavior                                                                                                                             |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `free`   | No charge. Used for lead magnets and free tiers.                                                                                     |
| `fixed`  | A set price in `amount` (cents).                                                                                                     |
| `custom` | Pay-what-you-want. The buyer chooses, bounded by `minimum_amount` / `maximum_amount`, with `preset_amount` as the suggested default. |

### `billing_type` — how often they pay

| Value          | Behavior                                                                                             |
| -------------- | ---------------------------------------------------------------------------------------------------- |
| `one_time`     | A single charge.                                                                                     |
| `subscription` | Recurring billing on `recurring_interval` (`day` \| `week` \| `month` \| `year`) × `interval_count`. |
| `payment_plan` | A fixed number of installments (`installment_count`) — pay in parts, then it ends.                   |

### Modifier fields

| Field                               | Type        | Applies to                   | Notes                                                                |
| ----------------------------------- | ----------- | ---------------------------- | -------------------------------------------------------------------- |
| `amount`                            | int (cents) | fixed                        | The price. `4900` = \$49.00.                                         |
| `currency`                          | string      | all                          | Lowercase ISO, e.g. `"usd"`.                                         |
| `recurring_interval`                | enum        | subscription                 | `day` \| `week` \| `month` \| `year`.                                |
| `interval_count`                    | int         | subscription                 | Multiplier — e.g. `month` × `3` = quarterly.                         |
| `installment_count`                 | int         | payment\_plan                | Number of installments.                                              |
| `setup_fee_amount`                  | int (cents) | subscription / payment\_plan | One-time fee charged up front.                                       |
| `trial_period_days`                 | int         | subscription                 | Free trial length before first charge.                               |
| `revoke_after_days`                 | int         | all                          | Auto-revoke access N days after purchase.                            |
| `minimum_amount` / `maximum_amount` | int (cents) | custom (PWYW)                | Bounds on what a buyer may pay.                                      |
| `preset_amount`                     | int (cents) | custom (PWYW)                | Suggested default amount.                                            |
| `quantity_available`                | int         | all                          | Caps how many can be sold — e.g. seats in a cohort or limited spots. |
| `waitlist`                          | bool        | all                          | Collect interest when sold out.                                      |
| `hidden`                            | bool        | all                          | Hide this variant from the website (still purchasable by link).      |
| `archived`                          | bool        | all                          | Retire this variant.                                                 |

<Note>
  The response also returns `discounted_from_amount` (for showing a strike-through "was" price), `benefits`, `purchase_url`, and `position` (ordering among a product's variants).
</Note>

## Worked examples

Each example below assumes you've already created a draft product `prod_abc123` and shows just the price variant. Remember to `PATCH` the product to `active` once at least one variant exists.

<Tabs>
  <Tab title="One-time">
    A single \$49 charge — the simplest sellable thing.

    ```bash theme={null}
    curl -X POST https://api.crevio.co/v1/price_variants \
      -H "Authorization: Bearer YOUR_API_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "product": "prod_abc123",
        "name": "Lifetime access",
        "amount_type": "fixed",
        "billing_type": "one_time",
        "amount": 4900,
        "currency": "usd"
      }'
    ```
  </Tab>

  <Tab title="Monthly subscription">
    \$19/month with a 7-day free trial.

    ```bash theme={null}
    curl -X POST https://api.crevio.co/v1/price_variants \
      -H "Authorization: Bearer YOUR_API_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "product": "prod_abc123",
        "name": "Monthly membership",
        "amount_type": "fixed",
        "billing_type": "subscription",
        "amount": 1900,
        "currency": "usd",
        "recurring_interval": "month",
        "interval_count": 1,
        "trial_period_days": 7
      }'
    ```
  </Tab>

  <Tab title="Payment plan">
    $300 total, split into 3 monthly installments of $100.

    ```bash theme={null}
    curl -X POST https://api.crevio.co/v1/price_variants \
      -H "Authorization: Bearer YOUR_API_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "product": "prod_abc123",
        "name": "Pay in 3",
        "amount_type": "fixed",
        "billing_type": "payment_plan",
        "amount": 10000,
        "currency": "usd",
        "recurring_interval": "month",
        "interval_count": 1,
        "installment_count": 3
      }'
    ```

    <Note>
      `amount` here is the per-installment charge. Three installments of `10000` (=$100.00) total $300.
    </Note>
  </Tab>

  <Tab title="Pay-what-you-want">
    Custom pricing — buyer chooses between $5 and $100, defaulting to \$25.

    ```bash theme={null}
    curl -X POST https://api.crevio.co/v1/price_variants \
      -H "Authorization: Bearer YOUR_API_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "product": "prod_abc123",
        "name": "Name your price",
        "amount_type": "custom",
        "billing_type": "one_time",
        "currency": "usd",
        "minimum_amount": 500,
        "maximum_amount": 10000,
        "preset_amount": 2500
      }'
    ```
  </Tab>

  <Tab title="Free lead magnet">
    No charge — capture leads in exchange for a download.

    ```bash theme={null}
    curl -X POST https://api.crevio.co/v1/price_variants \
      -H "Authorization: Bearer YOUR_API_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "product": "prod_abc123",
        "name": "Free download",
        "amount_type": "free",
        "billing_type": "one_time",
        "currency": "usd"
      }'
    ```
  </Tab>
</Tabs>

## Adding images

A product's gallery is set by passing an array of **MediaLibrary file ids** in `images`. The first id is the cover.

```bash theme={null}
curl -X PATCH https://api.crevio.co/v1/products/prod_abc123 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "images": ["file_cover123", "file_detail456"] }'
```

Get those `file_...` ids by uploading via `POST /files`, or by generating artwork with `POST /images/generate` (generated images land in your MediaLibrary automatically). Passing an empty array (`"images": []`) clears the gallery.

<Tip>
  You can ask Crevio to do this end-to-end: "generate cover art for the guitar course and set it as the product image." The agent generates the image, persists it to the MediaLibrary, and patches the product's `images` for you.
</Tip>

## Next steps

<CardGroup cols={2}>
  <Card title="Checkouts" icon="cart-shopping" href="/developer/guides/checkouts">
    Turn published price variants into payments with checkouts and checkout links.
  </Card>

  <Card title="Subscriptions & billing" icon="arrows-rotate" href="/developer/guides/subscriptions-and-billing">
    Manage the subscriptions, invoices, and refunds your price variants generate.
  </Card>

  <Card title="Discounts" icon="percent" href="/developer/guides/discounts">
    Add promo codes scoped to specific price variants.
  </Card>

  <Card title="Commerce overview" icon="diagram-project" href="/developer/guides/commerce-overview">
    Step back to the full mental model of how the primitives connect.
  </Card>
</CardGroup>
