# Subscription Products APIs for managing products within subscriptions including adding, removing, updating quantities, and swapping products. ## Update multiple properties of a subscription line item - [PUT /api/external/v2/subscription-contracts-update-line-item](https://developers.subscription.appstle.com/external-api-swagger/subscription-products/updatelineitemv2.md): Comprehensive endpoint for updating a subscription line item's quantity, price, product variant, and/or selling plan in a single API call. Changes are applied intelligently - only modified values trigger updates. Key Features: - Update any combination of: quantity, price, variant, or selling plan - Intelligent change detection - only updates what's different - Automatic handling of prepaid subscription pricing - Preserves existing discount cycles when updating price - Partial success allowed - some updates may fail while others succeed - Each change creates separate activity log entries Prepaid Subscription Handling: For prepaid subscriptions (billing interval > delivery interval): - When isPricePerUnit=true: Price is multiplied by interval ratio - Example: Monthly billing, weekly delivery = price × 4 - When isPricePerUnit=false: Price is used as total billing amount Update Process: 1. Validates line item exists in the subscription 2. Calculates interval multiplier for prepaid logic 3. Updates in order: selling plan → price → quantity → variant 4. Each update uses separate Shopify GraphQL mutation 5. Failures are logged but don't block other updates Selling Plan Updates: - Can update by ID or name (name takes precedence) - Only updates if different from current plan - Useful for changing delivery frequency options Price Updates: - Preserves existing discount cycles (up to 2 cycles) - Recalculates cycle discounts based on new base price - Triggers shipping price recalculation - Sends price update email to customer Quantity Updates: - Validates against min/max quantity rules - Updates Build-a-Box totals if applicable - May trigger discount recalculations Variant Updates: - Changes the product itself (different SKU) - Validates new variant exists and is available - May affect pricing and discounts Important Notes: - All parameters except contractId and lineId are optional - Provide only the values you want to change - Price is always in shop's base currency - Changes apply to future orders only Authentication: Requires valid X-API-Key header ## Update selling plan for a subscription line item - [PUT /api/external/v2/subscription-contracts-update-line-item-selling-plan](https://developers.subscription.appstle.com/external-api-swagger/subscription-products/updatelineitemsellingplan.md): Updates the selling plan associated with a specific product line item in a subscription contract. Selling plans define the delivery schedule, pricing rules, and billing policies for subscription products. What are Selling Plans? Selling plans are Shopify's way of defining subscription rules for products: - Delivery Schedule: How often the product is delivered (e.g., 'every 2 weeks', 'monthly') - Pricing Policy: Discounts and pricing tiers (e.g., '10% off', 'first order free') - Billing Policy: When and how often customer is charged - Plan Name: Customer-facing description like 'Deliver every month' Key Features: - Update by selling plan ID or name (name takes precedence if both provided) - Validates line item exists before attempting update - Only creates activity log if plan actually changes - Uses Shopify's draft system for safe updates - Preserves existing line item attributes and customizations Common Use Cases: - Change delivery frequency: Weekly → Monthly - Switch pricing tiers: Regular → VIP pricing - Update from old plan to new plan with better terms - Migrate products to new selling plan groups - Apply seasonal or promotional plans Update Process: 1. Validates subscription contract and line item exist 2. Creates a draft of the subscription contract 3. Updates the line item's selling plan in the draft 4. Commits the draft to apply changes 5. Records activity log if plan changed Impact of Selling Plan Changes: - Delivery Schedule: Next and future orders follow new schedule - Pricing: New plan's pricing applies from next billing - Discounts: Plan-specific discounts are recalculated - Billing: Billing frequency may change with the plan Finding Selling Plans: To find available selling plans: 1. Check product's selling plan groups in Shopify admin 2. Use Shopify's GraphQL API to query selling plans 3. Plans must be active and associated with the product Important Notes: - Both sellingPlanId and sellingPlanName are optional, but at least one required - If both provided, both are updated (name doesn't override ID) - Plan must be valid for the product variant - Changes apply to future orders only - No customer notification sent (consider sending separately) Authentication: Requires valid X-API-Key header ## Update product line item quantity in subscription - [PUT /api/external/v2/subscription-contracts-update-line-item-quantity](https://developers.subscription.appstle.com/external-api-swagger/subscription-products/updatelineitemquantityv2.md): Updates the quantity of a specific product line item within a subscription contract. This comprehensive operation handles quantity validation, discount recalculation, and special Build-a-Box constraints. Key Features: - Updates quantity for future orders only - Validates minimum/maximum quantities for line items - Special handling for Build-a-Box subscriptions - Automatic discount recalculation - Shipping price updates - Activity log tracking with old/new values Build-a-Box (BAB) Validation: For Build-a-Box subscriptions: - Enforces total minimum/maximum item counts - Only counts recurring products (excludes one-time and free items) - Validates across all BAB items in the subscription - Can be bypassed with 'allowToAddProductQuantityMinMaxReached' permission Line Item Validation: Individual products may have: - Minimum quantity requirements (min_quantity attribute) - Maximum quantity limits (max_quantity attribute) - These are enforced separately from BAB constraints Post-Update Actions: 1. Activity Logging: Records quantity change with old/new values 2. BAB Discount Sync: Recalculates Build-a-Box volume discounts 3. Product Discount Sync: Updates product-specific discounts 4. Shipping Price Update: Recalculates shipping based on new quantity Discount Recalculation: - Build-a-Box discounts adjust based on total quantity tiers - May remove old discount codes and apply new ones - Handles 'subscription contract has changed' retry scenarios Important Notes: - Line ID must be the full GraphQL ID format - Quantity must be positive (minimum 1) - Changes apply to all future orders - Past or in-progress orders are not affected Authentication: Requires valid X-API-Key header ## Update line item pricing policy with cycle-based discounts - [PUT /api/external/v2/subscription-contracts-update-line-item-pricing-policy](https://developers.subscription.appstle.com/external-api-swagger/subscription-products/updatelineitempricingpolicyv2.md): Sets up advanced pricing rules for a subscription line item that change based on the number of successful orders (cycles). This powerful feature enables loyalty discounts, promotional pricing tiers, and subscribe-and-save models. What are Pricing Policies? Pricing policies define how a product's price changes over the subscription lifetime: - Base Price: Starting price for the product - Cycle Discounts: Price changes after specific numbers of orders - Automatic Application: System applies correct price based on order history Supported Discount Types: - PERCENTAGE: Percentage off base price (e.g., 10% off) - FIXED: Fixed amount off base price (e.g., $5 off) - PRICE: Override with new fixed price (e.g., $19.99) Note: SHIPPING and FREE_PRODUCT types are not supported by this endpoint Cycle Counting: - Cycles start at 1 (first order is cycle 1) - Only successful billing attempts count - Failed payments don't increment the cycle - Current cycle = 1 + count of successful past orders Common Use Cases: 1. Subscribe & Save: 10% off starting from 3rd order 2. Loyalty Tiers: 5% off after 3 orders, 10% after 6 orders 3. Introductory Pricing: First 2 orders at $9.99, then $14.99 4. Promotional Periods: Special price for orders 3-5 Important Limitations: - Maximum 2 cycle discounts per line item - Cycles must have different afterCycle values - Changes apply to future orders only - Existing orders keep their original pricing Prepaid Subscription Handling: For prepaid subscriptions (e.g., pay monthly for weekly delivery): - Base price is per delivery - Current price = base price × delivery frequency - Discounts apply to base price, then multiply Side Effects: - Sends price update email to customer - Recalculates Build-a-Box discounts - Updates product discount synchronization - Triggers shipping price recalculation - Creates detailed activity log Authentication: Requires valid X-API-Key header ## Update product line item price - [PUT /api/external/v2/subscription-contracts-update-line-item-price](https://developers.subscription.appstle.com/external-api-swagger/subscription-products/updatelineitempricev2.md): Updates the base price of a specific product line item within a subscription contract. This endpoint intelligently handles pricing updates while preserving existing discount structures. Key Features: - Updates base price while maintaining discount cycles - Automatically calculates prepaid subscription prices - Preserves existing percentage/fixed discounts - Validates actual price changes before updating - Triggers shipping and discount recalculations - Sends price update notifications to customers Base Price vs Current Price: - Base Price: The unit price before any multipliers - Current Price: Base price × fulfillment multiplier - For monthly billing/weekly delivery: Current = Base × 4 - For pay-per-delivery: Current = Base × 1 Discount Preservation: By default, this endpoint preserves existing discount cycles: - Percentage discounts adjust to new base price - Fixed discounts remain at same dollar amount - Discount schedule (after X cycles) unchanged Prepaid Subscription Handling: For prepaid subscriptions (billing interval > delivery interval): - Automatically calculates fulfillment multiplier - Updates current price accordingly - Ensures correct billing amounts Post-Update Actions: 1. Build-a-Box discount recalculation 2. Product discount synchronization 3. Shipping price updates 4. Customer email notifications 5. Activity log creation Important Notes: - Price changes apply to future orders only - Cannot set price below $0.01 - Maximum 2 discount cycles preserved - No update if price unchanged Authentication: Requires valid X-API-Key header ## Remove multiple products from subscription - [PUT /api/external/v2/subscription-contracts-remove-line-items](https://developers.subscription.appstle.com/external-api-swagger/subscription-products/removelineitems.md): Removes multiple product line items from an existing subscription contract in a single request. Products are removed sequentially, allowing partial success if errors occur. Key Features: - Sequential processing - items removed one by one - Partial success allowed - previous removals persist if later ones fail - Validates each removal against current subscription state - Smart discount cleanup for line-specific discounts - Comprehensive validation for each product removal - Triggers all side effects after each successful removal Processing Order Matters: Items are removed in the order provided: 1. First item validated and removed 2. Second item validated against updated state 3. Continue until all processed or error occurs 4. Returns final subscription state Validation Per Item: - Line item must exist in subscription - At least one recurring product must remain - Build-a-Box min/max quantities maintained - Minimum cycle commitments honored - One-time and free products don't count toward minimum Discount Handling: When removeDiscount=true: - Removes discounts applied ONLY to the removed line - Preserves discounts that apply to multiple lines - Each removal evaluates discounts independently - Build-a-Box discounts auto-adjust based on quantity Side Effects Per Removal: Each successful removal triggers: - Activity log entry created - Customer email sent (except one-time products) - Shipping price recalculation - Build-a-Box discount resync - Product discount adjustments Partial Success Scenarios: If removing 3 items and the 2nd fails: - 1st item: Successfully removed - 2nd item: Fails, error returned - 3rd item: Not attempted - Result: Subscription with 1st item removed Performance Considerations: - Each removal is a separate Shopify API transaction - Multiple emails may be sent to customer - Consider using single remove for 1-2 items - Large batches may timeout - Recommended max: 5-10 items per request Build-a-Box Handling: For Build-a-Box subscriptions: - Validates total quantity after EACH removal - May fail mid-batch if minimum breached - Discounts recalculate after each item - Consider removal order carefully Important Notes: - NOT atomic - no rollback on partial failure - Order of line IDs affects success probability - Customer receives email per removed item - All validations apply as if removing individually - Response shows final state after all attempts Authentication: Requires valid X-API-Key header ## Remove product from subscription - [PUT /api/external/v2/subscription-contracts-remove-line-item](https://developers.subscription.appstle.com/external-api-swagger/subscription-products/removelineitemv2.md): Removes a specific product line item from an existing subscription contract. Can optionally retain prorated discounts associated with the removed product. Key Features: - Validates minimum subscription requirements before removal - Handles discount cleanup for line-specific discounts - Enforces minimum cycle commitments on products - Supports Build-a-Box quantity validation - Automatic retry on concurrent modification conflicts - Email notifications for subscription changes Validation Rules: - At least one recurring subscription product must remain after removal - One-time products and free products don't count toward the minimum - Products with minimum cycle commitments cannot be removed until fulfilled - Build-a-Box subscriptions validate against minimum/maximum quantity rules Discount Handling: When removeDiscount=true (default): - Discounts applied only to the removed line item are deleted - Discounts applied to multiple line items are retained - System automatically identifies which discounts to remove Retry Mechanism: The endpoint automatically retries in these scenarios: - Concurrent modification detected (another process updated the subscription) - Invalid discount code errors (removes problematic discount and retries) - This ensures reliable operation in high-traffic environments Post-Removal Actions: - Activity log created for audit trail - Email notification sent to customer (except for one-time products) - Shipping price recalculated asynchronously - Build-a-Box discounts resynced if applicable - Product-specific discounts resynced Authentication: Requires valid X-API-Key header ## Add multiple products to subscription - [PUT /api/external/v2/subscription-contracts-add-line-items](https://developers.subscription.appstle.com/external-api-swagger/subscription-products/addlineitems.md): Adds multiple product line items to an existing subscription contract in a single request. This batch operation is more efficient than making multiple individual requests and ensures all products are added with consistent processing. Key Features: - Batch addition of multiple products in one API call - All products are added as recurring items (not one-time) - Automatic quantity defaulting (0 or null becomes 1) - Sequential processing with full validation for each item - Returns final subscription state after all additions - Same pricing and discount logic as single-item endpoint Processing Behavior: - Products are added sequentially, not in parallel - If any product fails, previous additions remain - Each product goes through full validation - Existing product handling follows store settings - Activity logs created for each product added Duplicate Product Handling: If a product already exists in the subscription: - With 'updateExistingQuantityOnAddProduct' enabled: Updates quantity - Without setting: Adds as new line item - Setting applies to all products in the batch Pricing and Discounts: Each product receives: - Appropriate selling plan assignment - Discount carry-forward based on store settings - Currency and country-specific pricing - Fulfillment frequency multiplier application Build-a-Box Validation: - Applied if any product has _bb_id attribute - Validates total quantity after all additions - May fail entire batch if limits exceeded Post-Processing: After all products are added: - Build-a-Box discounts recalculated once - Product discounts synchronized - Single email notification sent - Shipping price updated once Important Notes: - Maximum recommended batch size: 10-20 products - Larger batches may timeout - All products become recurring items - Use single-item endpoint for one-time products Authentication: Requires valid X-API-Key header ## Add product to subscription - [PUT /api/external/v2/subscription-contracts-add-line-item](https://developers.subscription.appstle.com/external-api-swagger/subscription-products/addlineitemv2.md): Adds a new product line item to an existing subscription contract. Can add either recurring products that will appear in each order or one-time products that appear only in the next order. Key Features: - Supports both recurring and one-time product additions - Automatically applies appropriate pricing policies based on discount carry-forward settings - Handles duplicate products by updating quantity (if enabled) or adding as new line - Calculates prices based on billing/delivery frequency multipliers - Sends email notifications to customers (unless suppressed) - Creates activity logs for audit trail Pricing Policy Application: The system applies discounts based on the store's discount carry-forward setting: - PRODUCT_PLAN: Uses the discount from the product's selling plan - EXISTING_PLAN: Applies the discount structure from existing subscription items - PRODUCT_THEN_EXISTING: First attempts product plan, falls back to existing if not found One-Time Products: Products added with isOneTimeProduct=true will: - Only appear in the next scheduled order - Be automatically removed after fulfillment - Still attempt to match with appropriate selling plans - Can have subscription discounts applied if store setting allows Duplicate Product Handling: When adding a product that already exists in the subscription: - If store has 'updateExistingQuantityOnAddProduct' enabled and product is not one-time: Updates existing quantity - Otherwise: Adds as a new line item Price Calculation: - Base price is fetched considering contract currency and delivery country - Price is multiplied by fulfillment frequency ratio (billing interval / delivery interval) - Example: Monthly billing with weekly delivery = price × 4 Authentication: Requires valid X-API-Key header ## Add product with custom price to subscription - [PUT /api/external/v2/subscription-contract-add-line-item](https://developers.subscription.appstle.com/external-api-swagger/subscription-products/addlineitemv2_1.md): Adds a new product line item with a custom price override to an existing subscription contract. This endpoint bypasses standard pricing and selling plans to set an exact price. Key Features: - Direct price control - set any price regardless of product pricing - Optional automatic discount application based on shop settings - No selling plan assignment - pure custom pricing - Supports both recurring and one-time products - Email notifications sent to customers - Activity logging for audit trails Custom Pricing Behavior: - Price is set exactly as provided (no calculations) - Overrides any product-level pricing - Not affected by currency or country - No automatic discounts from selling plans - Price remains fixed unless manually updated Shop-Level Discount Application: Despite the method name, this endpoint MAY apply discounts: - Checks shop setting: 'applySubscriptionDiscount' - If enabled, applies shop's default subscription discount - Discount type: PERCENTAGE or FIXED (per shop config) - Creates manual discount: 'PRODUCT_DISCOUNT_[lineId]' - Discount is additional to the custom price Common Use Cases: - Negotiated Pricing: Custom rates for specific customers - Price Matching: Match competitor pricing - Promotional Pricing: Special one-off prices - Bundle Pricing: Custom prices for package deals - Legacy Pricing: Honor old pricing agreements - Test Orders: Zero or nominal pricing for testing Differences from Standard Add: - No selling plan association - No pricing policy rules - No automatic tier discounts - Price doesn't adjust with frequency changes - Manual price management required One-Time Products: When isOneTimeProduct=true: - Product appears only in next order - Automatically removed after fulfillment - Custom price applies to that single order - Shop discount still applies if configured Price Validation: - Must be a positive number - No maximum limit enforced - Can be less than product cost (loss leader) - Currency matches shop's base currency - Decimal precision per currency rules Important Considerations: - No automatic price updates with product changes - Frequency changes don't affect pricing - May bypass minimum order values - Consider margin implications - Document reason for custom pricing Post-Addition Effects: - Customer receives product addition email - Activity log records custom price - Shipping may need recalculation - Order total updates immediately - No impact on other line items Authentication: Requires valid X-API-Key header