Manual Setup

This comprehensive guide walks you through manually creating plans, features, metrics, prices, and credits using Lumen's API. This approach gives you complete control over your billing structure and is ideal for complex scenarios or when you need precise configuration.

Overview

Creating a complete billing plan involves several interconnected components:

  1. Plan - The core plan entity
  2. Features - Individual capabilities that customers get access to
  3. Metrics - Usage tracking for features (when applicable)
  4. Prices - Pricing structures (fixed, per-seat, usage-based)
  5. Credit Definitions - Credit systems for usage allowances
  6. Linking - Connecting all components together

Step 1: Create the Core Plan

Start by creating the basic plan structure:

curl -X POST "https://api.getlumen.dev/v1/plans" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "planName": "Professional Plan",
    "planDescription": "Full-featured plan for growing teams",
    "versionNumber": 1,
    "commitMessage": "Initial Professional Plan setup"
  }'

Response:

{
  "plans": [{
    "id": "plan_abc123",
    "planName": "Professional Plan",
    "planDescription": "Full-featured plan for growing teams",
    "versionNumber": 1,
    "merchantId": "merchant_xyz789",
    "stablePlanId": "stable_plan_def456",
    "createdAt": "2024-01-15T10:00:00.000Z"
  }]
}

Keep the plan_abc123 ID - you'll need it for subsequent steps.

Step 2: Create Features

Features represent the capabilities your customers get. Create each feature individually:

Boolean Features (On/Off Access)

For features that are either available or not:

curl -X POST "https://api.getlumen.dev/v1/features" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "advanced-analytics",
    "displayName": "Advanced Analytics",
    "description": "Access to detailed analytics and reporting",
    "featureValue": true,
    "isOverrideFeature": false
  }'

Numeric Features (Usage-Based)

For features with usage limits or counters:

curl -X POST "https://api.getlumen.dev/v1/features" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "api-calls",
    "displayName": "API Calls",
    "description": "Number of API calls per month",
    "featureValue": "usage_based",
    "isOverrideFeature": false
  }'

Important: Save the feature IDs from the responses - you'll need them to link features to your plan.

Step 3: Create Metrics (For Usage-Based Features)

If you have usage-based features, create metrics to track usage:

Simple Event Metrics

For straightforward event counting:

curl -X POST "https://api.getlumen.dev/v1/metrics" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "API Calls Metric",
    "description": "Tracks API call usage",
    "queryType": "simple",
    "aggregationType": "SUM",
    "eventName": "api_call",
    "valueType": "NUMERIC"
  }'

Complex SQL Metrics

For advanced usage calculations (like seat counting):

curl -X POST "https://api.getlumen.dev/v1/metrics" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Active Seats Count",
    "description": "Counts active users for seat-based billing",
    "queryType": "complex",
    "sqlDefinition": "SELECT COUNT(DISTINCT event_string) as value FROM events WHERE merchant_id = $1 AND customer_id = $2 AND event_name = '\''seat_added'\'' AND event_timestamp >= $4 AND event_timestamp <= $5"
  }'

Connect your features to the plan by creating a new plan version with the selected features:

curl -X POST "https://api.getlumen.dev/v1/plans/plan_abc123" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "featureIds": [
      "feature_analytics123",
      "feature_apicalls456"
    ],
    "commitMessage": "Attach analytics + api calls to plan"
  }'

For usage-based features, connect metrics by updating the feature with metric IDs:

curl -X PUT "https://api.getlumen.dev/v1/features/feature_apicalls456" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metricIds": ["metric_apicalls789"]
  }'

Step 6: Create Pricing

Define how customers will be charged. You can create multiple prices for different billing cycles.

Fixed Monthly Pricing

curl -X POST "https://api.getlumen.dev/v1/prices" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "planId": "plan_abc123",
    "currency": "USD",
    "pricingData": {
      "dsl_version": 1,
      "components": [{
        "type": "fixed",
        "component_name": "monthly",
        "label": "Professional Plan - $99.00 per month",
        "amount_cents": 9900,
        "recurrence_rule": "RRULE:FREQ=MONTHLY;INTERVAL=1",
        "bill_immediately": true
      }]
    }
  }'

Per-Seat Pricing

For seat-based billing:

curl -X POST "https://api.getlumen.dev/v1/prices" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "planId": "plan_abc123",
    "currency": "USD",
    "pricingData": {
      "dsl_version": 1,
      "components": [{
        "type": "per_unit",
        "component_name": "per_seat_monthly",
        "label": "Professional Plan - $25.00 per seat per month",
        "unit_label": "seat",
        "metric_id": "metric_seats123",
        "amount_cents": 2500,
        "num_seats": 2,
        "recurrence_rule": "RRULE:FREQ=MONTHLY;INTERVAL=1",
        "bill_immediately": true
      }]
    }
  }'

Usage-Based Pricing

Add usage-based components:

curl -X POST "https://api.getlumen.dev/v1/prices" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "planId": "plan_abc123",
    "currency": "USD",
    "pricingData": {
      "dsl_version": 1,
      "components": [{
        "type": "fixed",
        "component_name": "monthly",
        "label": "Professional Plan Base - $49.00",
        "amount_cents": 4900,
        "recurrence_rule": "RRULE:FREQ=MONTHLY;INTERVAL=1",
        "bill_immediately": true
      }, {
        "type": "usage",
        "component_name": "usage_api_calls",
        "label": "API Calls - $0.01 per call",
        "unit_label": "call",
        "metric_id": "metric_apicalls789",
        "unit_cost_cents": 1,
        "recurrence_rule": "RRULE:FREQ=MONTHLY;INTERVAL=1",
        "bill_immediately": false
      }]
    }
  }'

Annual Pricing

Create yearly alternatives with discounts:

curl -X POST "https://api.getlumen.dev/v1/prices" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "planId": "plan_abc123",
    "currency": "USD",
    "pricingData": {
      "dsl_version": 1,
      "components": [{
        "type": "fixed",
        "component_name": "annual",
        "label": "Professional Plan - $990.00 × 12 billed yearly (2 months free)",
        "amount_cents": 99000,
        "recurrence_rule": "RRULE:FREQ=YEARLY;INTERVAL=1",
        "bill_immediately": true
      }]
    }
  }'

Step 7: Create Credit Definitions

Set up usage allowances and credits:

Usage Credits (For Free Allowances)

curl -X POST "https://api.getlumen.dev/v1/credits/definitions" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": "plan",
    "applicationType": "usage",
    "planId": "plan_abc123",
    "featureId": "feature_apicalls456",
    "featureSlug": "api-calls",
    "priceId": "price_abc123",
    "priceComponentId": "pc_abc123", // Use the actual component_id from the created price
    "name": "API Call Credits",
    "description": "Monthly API call allowance",
    "defaultAmount": 10000,
    "refillAmount": 10000,
    "renewOnBilling": true,
    "billingVisible": false,
    "priority": 100
  }'

Monetary Credits

For dollar-value credits that apply to invoices:

curl -X POST "https://api.getlumen.dev/v1/credits/definitions" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": "plan",
    "applicationType": "monetary",
    "planId": "plan_abc123",
    "currency": "USD",
    "name": "Professional Plan Credit",
    "description": "Monthly account credit",
    "defaultAmount": 2500,
    "refillAmount": 2500,
    "renewOnBilling": true,
    "billingVisible": true,
    "billingDescription": "Monthly Account Credit",
    "priority": 50
  }'

Common Patterns

Free Plan Setup

# 1. Create free plan
curl -X POST "https://api.getlumen.dev/v1/plans" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "planName": "Free Plan",
    "planDescription": "Get started with basic features",
    "versionNumber": 1
  }'

# 2. Create $0 pricing
curl -X POST "https://api.getlumen.dev/v1/prices" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "planId": "plan_free123",
    "currency": "USD",
    "pricingData": {
      "dsl_version": 1,
      "components": [{
        "type": "fixed",
        "component_name": "monthly",
        "label": "Free Plan",
        "amount_cents": 0,
        "recurrence_rule": "RRULE:FREQ=MONTHLY;INTERVAL=1",
        "bill_immediately": true
      }]
    }
  }'

# 3. Add usage limits via credits
curl -X POST "https://api.getlumen.dev/v1/credits/definitions" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": "plan",
    "applicationType": "usage",
    "planId": "plan_free123",
    "featureId": "feature_apicalls456",
    "name": "Free API Calls",
    "defaultAmount": 1000,
    "refillAmount": 1000,
    "renewOnBilling": true
  }'

Enterprise Plan Setup

# 1. Create enterprise plan
curl -X POST "https://api.getlumen.dev/v1/plans" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "planName": "Enterprise",
    "planDescription": "Custom enterprise solution",
    "versionNumber": 1,
    "showInPricingTable": true,
    "isEnterprisePlan": true,
    "enterpriseButtonText": "Contact Sales",
    "enterpriseRedirectUrl": "https://yoursite.com/contact"
  }'

# Note: Skip pricing creation for enterprise plans
# Customers will contact sales for custom pricing

Usage-Only Plans

For plans with no fixed fee, only usage-based charges:

curl -X POST "https://api.getlumen.dev/v1/prices" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "planId": "plan_payasyougo123",
    "currency": "USD",
    "pricingData": {
      "dsl_version": 1,
      "components": [{
        "type": "usage",
        "component_name": "usage_api_calls",
        "label": "API Calls - $0.005 per call",
        "unit_label": "call",
        "metric_id": "metric_apicalls789",
        "unit_cost_cents": 0.5,
        "recurrence_rule": "RRULE:FREQ=MONTHLY;INTERVAL=1",
        "bill_immediately": false
      }]
    }
  }'

Advanced Configuration

Trial Plans

Create a plan and automatically provision a trial variant by including a trial configuration:

curl -X POST "https://api.getlumen.dev/v1/plans" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "planName": "Professional",
    "planDescription": "14-day trial of Professional Plan",
    "versionNumber": 1,
    "trial": { "enabled": true, "days": 14 }
  }'

Credit Renewal Options

Configure how credits renew:

# Billing-based renewal (renews with subscription billing cycle)
{
  "renewOnBilling": true
}

# RRULE-based renewal (independent schedule)
{
  "renewOnBilling": false,
  "refillRrule": "RRULE:FREQ=MONTHLY;INTERVAL=1"
}

# One-time credits (no renewal)
{
  "renewOnBilling": false,
  "expiryDays": 365
}

Validation and Testing

Verify Plan Structure

Check that everything is properly linked:

curl -X GET "https://api.getlumen.dev/v1/plans/plan_abc123?includeFeatures=true&includePrices=true" \
  -H "Authorization: Bearer $LUMEN_API_KEY"

Test Subscription Creation

Create a test subscription to verify billing works:

curl -X POST "https://api.getlumen.dev/v1/subscriptions" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "customer_test123",
    "planId": "plan_abc123",
    "effectivePriceId": "price_monthly123"
  }'

Send Test Events

For usage-based features, send test events:

curl -X POST "https://api.getlumen.dev/v1/events" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "customer_test123",
    "eventName": "api_call",
    "eventValue": 1,
    "properties": {
      "endpoint": "/api/v1/users",
      "method": "GET"
    }
  }'

Best Practices

  1. Plan Your Structure First - Map out your features, pricing, and credits before creating anything
  2. Use Descriptive Names - Make component names and labels clear for billing transparency
  3. Test Each Step - Verify each component works before moving to the next
  4. Version Control - Use version numbers and commit messages to track plan changes
  5. Credit Priorities - Set appropriate priority levels for different credit types
  6. Currency Consistency - Keep all pricing in the same currency per plan

Troubleshooting

Common Issues

Feature not showing up in plan:

  • Verify the feature was linked by creating a new plan version with featureIds (POST /plans/:id)
  • Check that feature IDs are correct

Usage not being tracked:

  • Confirm metric is linked to the feature (PUT /features/:id with metricIds)
  • Verify event names match exactly between metrics and events
  • Check that events are being sent with the correct customer ID and include eventValue or eventString

Credits not applying:

  • Ensure credit definitions have correct scope and application type
  • Verify price and component IDs match in credit definitions (priceComponentId must be the component_id)
  • Check that credit grants were created for the customer

Billing not working:

  • Confirm at least one price component exists for the plan
  • Verify price components have valid recurrence rules
  • Check that the subscription uses the correct effectivePriceId

Getting Help

  • Check the API documentation for each endpoint
  • Use the merchant dashboard to verify configurations
  • Contact support with specific plan IDs and error messages

This manual approach gives you complete control over your billing setup but requires careful attention to the relationships between components. Start simple and add complexity as needed.