Skip to main content
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.
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.
Course content (lessons, modules, drip) lives under Experiences, 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.

Recipe

1

Create the product as a draft

Money is never involved here yet — just the listing.
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."
  }'
{
  "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.
2

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.
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"
  }'
{
  "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.
3

Publish the product

Now that a price exists, flip the product to active.
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" }'
{
  "id": "prod_abc123",
  "object": "product",
  "status": "active"
}
4

Create a shareable checkout link

A checkout link is a reusable buy URL you can drop in emails, social posts, or your site.
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
  }'
{
  "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.
5

(Optional) Add a launch discount

Create a promo code and scope it to this price variant.
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"]
  }'
{
  "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.
Programmatic checkout instead of a shareable link? Call POST /checkouts with line_items: [{ price_variant: "price_xyz789", quantity: 1 }] and optionally a discount_code.

Next steps

AI content generation

Generate a cover image and attach it to the product.

Spin up a website

Put your product on an AI-built site with a custom domain.

Webhooks

Get notified on order.paid to fulfill automatically.

Conventions

Why draft-before-active and cents matter.