> ## 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.

# Launch a paid course

> Create a product, price it, publish it, and generate a shareable checkout link — the full sequence, in the order that works.

**Selling a paid course is four chained calls, and the order matters.** You create the product as a draft, attach at least one price variant, flip it to active, then mint a checkout link. Skip a step or reorder it and you'll hit a `422`.

<Warning>
  You cannot create a product with `status: "active"` in one shot — publishing requires at least one price variant first. Always: create draft → add price variant → PATCH to active.
</Warning>

<Note>
  Course **content** (lessons, modules, drip) lives under [Experiences](/developer/guides/conventions), managed in-app. The Experiences API is read-only (`GET /experiences`). A product bundles experiences through its price variants. This recipe covers the sellable side — product, price, and checkout.
</Note>

## Recipe

<Steps>
  <Step title="Create the product as a draft">
    Money is never involved here yet — just the listing.

    ```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": "Mastering Espresso at Home",
        "status": "draft",
        "description": "A 6-week video course on dialing in espresso."
      }'
    ```

    ```json theme={null}
    {
      "id": "prod_abc123",
      "object": "product",
      "name": "Mastering Espresso at Home",
      "status": "draft",
      "slug": "mastering-espresso-at-home",
      "images": [],
      "created_at": "2026-06-21T10:00:00Z"
    }
    ```

    Hold onto `prod_abc123`.
  </Step>

  <Step title="Add a fixed price variant">
    Associations are bare-name + prefixed id: `product: "prod_abc123"`, not `product_id`. Money is integer **cents** with a lowercase currency.

    ```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",
        "amount": 14900,
        "currency": "usd",
        "billing_type": "one_time"
      }'
    ```

    ```json theme={null}
    {
      "id": "price_xyz789",
      "object": "price_variant",
      "product": "prod_abc123",
      "name": "Full course",
      "amount_type": "fixed",
      "amount": 14900,
      "currency": "usd",
      "billing_type": "one_time",
      "purchase_url": "https://yourname.crevio.app/..."
    }
    ```

    `amount: 14900` is **\$149.00**. For a subscription, use `billing_type: "subscription"` plus `recurring_interval` and `interval_count`.
  </Step>

  <Step title="Publish the product">
    Now that a price exists, flip the product to `active`.

    ```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" }'
    ```

    ```json theme={null}
    {
      "id": "prod_abc123",
      "object": "product",
      "status": "active"
    }
    ```
  </Step>

  <Step title="Create a shareable checkout link">
    A checkout link is a reusable buy URL you can drop in emails, social posts, or your site.

    ```bash theme={null}
    curl -X POST https://api.crevio.co/v1/checkout_links \
      -H "Authorization: Bearer YOUR_API_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Espresso course launch",
        "price_variants": ["price_xyz789"],
        "allow_discount_codes": true
      }'
    ```

    ```json theme={null}
    {
      "id": "cl_link01",
      "object": "checkout_link",
      "name": "Espresso course launch",
      "price_variants": ["price_xyz789"],
      "allow_discount_codes": true
    }
    ```

    Share the link's URL and you're live.
  </Step>

  <Step title="(Optional) Add a launch discount">
    Create a promo code and scope it to this price variant.

    ```bash theme={null}
    curl -X POST https://api.crevio.co/v1/discounts \
      -H "Authorization: Bearer YOUR_API_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "code": "LAUNCH20",
        "discount_type": "percentage",
        "percent_off": 20,
        "duration": "once",
        "price_variants": ["price_xyz789"]
      }'
    ```

    ```json theme={null}
    {
      "id": "disc_promo01",
      "object": "discount",
      "code": "LAUNCH20",
      "discount_type": "percentage",
      "percent_off": 20,
      "duration": "once"
    }
    ```

    Because the checkout link was created with `allow_discount_codes: true`, buyers can enter `LAUNCH20` at checkout.
  </Step>
</Steps>

<Tip>
  Programmatic checkout instead of a shareable link? Call `POST /checkouts` with `line_items: [{ price_variant: "price_xyz789", quantity: 1 }]` and optionally a `discount_code`.
</Tip>

## Next steps

<CardGroup cols={2}>
  <Card title="AI content generation" icon="image" href="/developer/guides/ai-content">
    Generate a cover image and attach it to the product.
  </Card>

  <Card title="Spin up a website" icon="globe" href="/developer/guides/recipe-ai-website">
    Put your product on an AI-built site with a custom domain.
  </Card>

  <Card title="Webhooks" icon="bell" href="/developer/guides/webhooks">
    Get notified on `order.paid` to fulfill automatically.
  </Card>

  <Card title="Conventions" icon="list-check" href="/developer/guides/conventions">
    Why draft-before-active and cents matter.
  </Card>
</CardGroup>
