openapi: 3.0.1
info:
  title: External
  description: ''
  version: 0.0.1
servers:
  - url: https://membership-admin.appstle.com
tags:
  - name: Shipping & Delivery Profiles
    description: >-
      APIs for managing Shopify delivery profiles, shipping rates, zones, and
      free shipping configuration for subscription memberships
  - name: Customer Discount History
    description: >-
      APIs for retrieving historical discount code usage and redemption
      information for membership contracts
  - name: Cancellation Flow Configuration
    description: >-
      APIs for managing membership cancellation flow settings including
      retention offers, survey questions, and cancel confirmation screens
  - name: Billing & Orders
    description: >-
      APIs for managing membership billing attempts, recurring orders, payment
      retries, order history, and order skipping
  - name: One-Time Add-Ons
    description: >-
      APIs for managing one-time product additions to upcoming subscription
      orders, including adding, retrieving, and removing one-off items
  - name: Membership Plans
    description: >-
      APIs for managing membership/subscription plan groups, including creating
      plans, configuring discounts, billing intervals, and assigning products to
      plans
  - name: Product Bundles
    description: >-
      APIs for managing subscription product bundles, bundle configurations,
      item grouping, and bundle-specific discount codes
  - name: Custom CSS Styling
    description: >-
      APIs for retrieving custom CSS styles applied to subscription widgets and
      customer portal for theme customization
  - name: Customer Portal Configuration
    description: >-
      APIs for managing customer portal settings including UI customization,
      text labels, feature toggles, and branding options for the member
      self-service portal
  - name: Membership Contracts
    description: >-
      APIs for managing membership/subscription contracts including creation,
      updates, status changes, line items, discounts, and billing operations
  - name: Bundle Settings
    description: >-
      APIs for managing subscription bundle configuration settings including
      bundle behavior, pricing rules, and display options
  - name: Customer Payment Methods
    description: >-
      APIs for managing customer payment methods, payment tokens, and payment
      method retrieval for subscriptions
  - name: Product Swap Rules
    description: >-
      APIs for retrieving product swap/substitution options allowing members to
      exchange subscription items based on configured swap rules and variant
      groups
paths:
  /api/external/v2/subscription-contracts-update-status:
    put:
      tags:
        - Subscription Contract Management
        - Membership Contracts
      summary: Update subscription contract status (pause/resume/activate)
      description: >-
        Changes the status of a subscription contract. This allows pausing,
        resuming, or activating subscriptions to control billing and delivery.


        **Key Features:**

        - **Pause Subscriptions**: Temporarily stop billing and deliveries

        - **Resume Subscriptions**: Reactivate paused subscriptions

        - **Activate Subscriptions**: Start inactive subscriptions

        - **Activity Logging**: All status changes are logged for audit trail

        - **Customer Restrictions**: Includes minimum cycle checks when called
        from customer portal


        **Status Values:**

        - **ACTIVE**: Subscription is active and billing/delivering normally

        - **PAUSED**: Subscription is temporarily paused (no billing, no
        deliveries)

        - **CANCELLED**: Subscription is cancelled (use DELETE endpoint instead)


        **Pause vs. Cancel:**

        - **Pause**: Temporary hold, customer can resume anytime

        - **Cancel**: Permanent termination, requires creating new subscription
        to restart


        **Common Use Cases:**

        - **Vacation Hold**: Customer going on vacation, pause deliveries
        temporarily

        - **Financial Pause**: Customer needs temporary break from payments

        - **Product Surplus**: Customer has too much product, pause until they
        use it

        - **Seasonal Pause**: Pause subscriptions during off-season (e.g., lawn
        care in winter)

        - **Resume After Pause**: Customer ready to restart after temporary hold

        - **Reactivate Failed**: Reactivate subscription after payment method
        updated


        **Pause Behavior:**

        - **Billing Paused**: No charges while paused

        - **Deliveries Paused**: No orders created while paused

        - **Next Billing Date**: Preserved or recalculated on resume (merchant
        setting)

        - **Unlimited Duration**: Pauses can be indefinite unless merchant sets
        limits


        **Resume Behavior:**

        - **Immediate Reactivation**: Subscription becomes active immediately

        - **Next Billing Date**: Calculated based on pause duration settings

        - **Deliveries Resume**: Next delivery scheduled according to interval


        **Customer Portal Restrictions:**

        When called from customer portal (vs. merchant API):

        - **Minimum Cycles**: Cannot pause/cancel until minimum billing cycles
        met

        - **Freeze Period**: Updates may be frozen until minimum requirements
        satisfied

        - **Retention Rules**: Special retention discounts may be offered on
        cancellation


        **Important Notes:**

        - **Customer Communication**: Consider sending email notifications on
        status changes

        - **Billing Cycles Not Lost**: Paused cycles don't count toward minimums

        - **No Pro-rata**: No refunds or credits when pausing mid-cycle


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: updateStatusV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 12345
        - name: status
          in: query
          description: New subscription status
          required: true
          schema:
            type: string
            enum:
              - ACTIVE
              - PAUSED
          example: PAUSED
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      responses:
        '204':
          description: Subscription status successfully updated (no content returned)
        '400':
          description: Invalid status value or validation failed
          content:
            application/json:
              example:
                title: Bad Request
                status: 400
                detail: Invalid subscription status
        '401':
          description: Authentication required - invalid or missing API key
        '403':
          description: Action forbidden - minimum billing cycles not met or updates frozen
          content:
            application/json:
              example:
                title: Forbidden
                status: 403
                detail: >-
                  Cannot pause subscription until minimum billing cycles
                  completed
        '404':
          description: Subscription contract not found
        '500':
          description: Shopify API error during status update
  /api/external/v2/subscription-contracts-update-shipping-address:
    put:
      tags:
        - Subscription Contract Management
        - Membership Contracts
      summary: Update shipping address for subscription contract
      description: >-
        Changes the delivery shipping address for a subscription contract. This
        allows customers to update where their subscription orders are
        delivered.


        **Key Features:**

        - **Full Address Update**: Change complete shipping address in one call

        - **Address Validation**: System validates address format and country
        codes

        - **Immediate Effect**: New address applies to the next delivery

        - **Activity Logging**: All address changes are logged for audit trail

        - **International Support**: Supports addresses in all countries


        **Required Address Fields:**

        - **firstName**: Recipient's first name

        - **lastName**: Recipient's last name

        - **address1**: Street address line 1

        - **city**: City name

        - **countryCode**: ISO 3166-1 alpha-2 country code (e.g., US, CA, GB)

        - **zip**: Postal/ZIP code


        **Optional Address Fields:**

        - **address2**: Apartment, suite, unit number

        - **company**: Company name (for business addresses)

        - **phone**: Contact phone number

        - **provinceCode**: State/province code (e.g., CA, NY, ON)


        **Common Use Cases:**

        - **Customer Moved**: Update address after relocation

        - **Temporary Address**: Ship to vacation home or temporary location

        - **Gift Recipient**: Change recipient for gift subscriptions

        - **Correct Typos**: Fix address errors from initial signup

        - **Business to Home**: Switch between business and residential
        addresses

        - **Seasonal Address**: Update for snowbird/seasonal residents


        **Country and Province Codes:**

        - **countryCode**: Use ISO 3166-1 alpha-2 codes
          - Examples: US (United States), CA (Canada), GB (United Kingdom), AU (Australia)
        - **provinceCode**: Use ISO 3166-2 subdivision codes
          - US Examples: CA (California), NY (New York), TX (Texas)
          - Canada Examples: ON (Ontario), BC (British Columbia), QC (Quebec)

        **Address Validation:**

        - **Format Validation**: System checks required fields are present

        - **Country Validation**: Verifies country code is valid

        - **Province Validation**: Checks province code matches country

        - **Postal Code**: Validates postal code format for country


        **Important Notes:**

        - **Shipping Rate Recalculation**: New address may have different
        shipping costs

        - **Delivery Method**: System automatically selects appropriate delivery
        method

        - **Next Order Only**: Only affects future orders, not orders already
        placed

        - **Address Book**: Consider updating customer's default address
        separately

        - **PO Boxes**: Some delivery methods may not support PO Box addresses


        **Shipping Cost Impact:**

        - Changing address may change shipping costs for future deliveries

        - International addresses typically have higher shipping costs

        - Remote/rural areas may have additional delivery fees

        - Consider notifying customer of cost changes


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: updateShippingAddressV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 12345
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      requestBody:
        description: New shipping address details
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChangeShippingAddressVM'
            examples:
              US Address Example:
                description: US Address Example
                value:
                  firstName: John
                  lastName: Doe
                  address1: 123 Main Street
                  address2: Apt 4B
                  city: San Francisco
                  provinceCode: CA
                  countryCode: US
                  zip: '94102'
                  phone: +1-415-555-0123
                  company: Acme Corp
        required: true
      responses:
        '200':
          description: Shipping address successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: Invalid address format or missing required fields
          content:
            application/json:
              examples:
                Missing required field:
                  description: Missing required field
                  value:
                    title: Bad Request
                    status: 400
                    detail: 'Required address field missing: countryCode'
                Invalid country code:
                  description: Invalid country code
                  value:
                    title: Bad Request
                    status: 400
                    detail: 'Invalid country code: XX'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '500':
          description: Shopify API error during address update
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-contracts-update-payment-method:
    put:
      tags:
        - Membership Contracts
      summary: Update subscription payment method
      description: >-
        Updates the payment method for a subscription contract by refreshing
        payment instrument from Shopify customer. This endpoint syncs the
        subscription's payment method with the customer's default payment method
        in Shopify.


        **Payment Method Update Process:**

        - **Fetch Latest Payment**: Retrieves customer's current default payment
        method from Shopify

        - **Update Contract**: Associates new payment method with subscription
        contract

        - **Validate Payment**: Ensures payment method is valid and active

        - **Sync Changes**: Updates payment instrument in subscription billing
        system


        **Key Features:**

        - **Automatic Sync**: Pulls latest payment method from Shopify customer
        record

        - **Payment Validation**: Verifies new payment method is usable for
        billing

        - **Contract Update**: Updates Shopify subscription contract with new
        payment

        - **Failed Billing Recovery**: Useful for updating payment after billing
        failures


        **Use Cases:**

        - Customer updates credit card and wants to apply to existing
        subscription

        - Recover from failed billing by allowing payment method update

        - Sync payment methods in customer portal workflows

        - Update expired or invalid payment methods

        - Switch between multiple saved payment methods

        - Integration with custom payment update flows


        **Important Notes:**

        - Customer must have a default payment method in Shopify

        - Payment method must be valid and not expired

        - Updates are reflected immediately for future billing

        - Does not retry failed billing attempts automatically


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: updatePaymentMethodV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID to update payment method for
          required: true
          schema:
            type: integer
            format: int64
          example: 123456789
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Payment method successfully updated for subscription
        '400':
          description: Invalid contract ID or no valid payment method found
        '401':
          description: Authentication required - invalid or missing API key
        '404':
          description: Subscription contract not found
        '500':
          description: Shopify API error during payment method update
  /api/external/v2/subscription-contracts-update-order-note/{contractId}:
    put:
      tags:
        - Membership Contracts
      summary: Update order note/instructions for subscription contract
      description: >-
        Updates the persistent order note attached to a subscription contract.
        This note is automatically included with **EVERY future recurring
        order** generated from this subscription, appearing in Shopify admin
        order details and printable packing slips.


        **IMPORTANT: Recurring vs One-Time Notes**

        - **This Endpoint (Contract Note)**: Applies to **ALL FUTURE ORDERS**
        permanently

        - **Billing Attempt Note**
        (`/subscription-billing-attempts-update-order-note`): Applies to **ONE
        SPECIFIC ORDER** only

        - **Combined Behavior**: If both notes exist, they are concatenated in
        the Shopify order


        **How It Works:**

        1. Accepts subscription contract ID and new order note text

        2. Stores note in subscription contract record

        3. Every time a new order is created (monthly, weekly, etc.), note is
        automatically added

        4. Previous contract note is replaced (not appended)

        5. Empty string clears the existing note

        6. Does NOT affect past orders already created


        **Character Limits & Validation:**

        - **Maximum Length**: 5000 characters (Shopify order note limit)

        - **Encoding**: UTF-8 supported (emojis, international characters
        allowed)

        - **HTML**: Plain text only - HTML tags display as text

        - **Line Breaks**: Use `\n` for line breaks (preserved in Shopify)

        - **Special Characters**: Automatically escaped for safety


        **Common Use Cases:**


        **1. Permanent Delivery Instructions**

        ```

        Example: "Always leave package at back door. Do not ring doorbell (baby
        sleeping)."

        Use Case: Customer wants same delivery instructions for all future
        orders

        Applies To: Every monthly shipment permanently

        ```


        **2. Gift Subscription Messages**

        ```

        Example: "This is a gift subscription for Mom. Happy Birthday! Love,
        Sarah"

        Use Case: Gift subscription with recurring message

        Applies To: All orders until subscription ends or note is changed

        ```


        **3. Special Handling Requirements**

        ```

        Example: "FRAGILE - Glass bottles. Handle with care. Keep upright during
        shipping."

        Use Case: Delicate products requiring special warehouse handling

        Applies To: Every fulfillment automatically

        ```


        **4. Customer Preferences**

        ```

        Example: "Customer is allergic to peanuts. NO peanut products.
        Double-check packaging."

        Use Case: Critical dietary restrictions or preferences

        Applies To: All future orders for safety compliance

        ```


        **5. Internal Merchant Notes**

        ```

        Example: "VIP customer - priority processing. Include bonus samples."

        Use Case: Internal fulfillment team instructions

        Applies To: All shipments to provide consistent VIP treatment

        ```


        **6. Clearing Unwanted Notes**

        ```

        Example: orderNote="" (empty string)

        Use Case: Customer moved, no longer needs "Leave at neighbor" note

        Result: Future orders have no contract note (one-time notes still
        possible)

        ```


        **Where Note Appears:**

        - **Shopify Admin**: Order details page under "Notes"

        - **Packing Slips**: Printed on warehouse packing slips (if enabled)

        - **Order Confirmation Emails**: May appear in customer emails
        (theme-dependent)

        - **Fulfillment Apps**: Visible to third-party logistics providers

        - **Order APIs**: Accessible via Shopify Order REST/GraphQL APIs


        **When to Use Contract Note vs Billing Attempt Note:**


        | Scenario | Use Contract Note | Use Billing Attempt Note |

        |----------|-------------------|-------------------------|

        | Permanent delivery instructions | ✅ | ❌ |

        | One-time special request | ❌ | ✅ |

        | Gift message for all shipments | ✅ | ❌ |

        | "Skip broccoli this week" | ❌ | ✅ |

        | Allergy warnings | ✅ | ❌ |

        | "Deliver to neighbor (vacation week)" | ❌ | ✅ |

        | VIP customer priority | ✅ | ❌ |


        **Error Handling:**


        **400 - Bad Request:**

        - Order note exceeds 5000 character limit

        - Contract ID doesn't belong to authenticated shop

        - Contract is in invalid state


        **404 - Contract Not Found:**

        - Subscription contract ID doesn't exist

        - Contract was deleted

        - Wrong shop (contract belongs to different store)


        **Integration Best Practices:**

        1. **Display Character Counter**: Show "450 / 5000 characters" in UI

        2. **Preview Formatting**: Show how line breaks will appear

        3. **Confirm Permanent Changes**: Warn user "This note will appear on
        ALL future orders"

        4. **Sanitize Input**: Strip HTML tags, prevent injection attacks

        5. **Show Current Note**: Pre-fill form with existing note before update


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: updateOrderNoteV2
      parameters:
        - name: contractId
          in: path
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 12345
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: orderNote
          in: query
          description: Custom order note/instructions to include with subscription orders
          required: true
          schema:
            type: string
          example: Please leave at back door
      responses:
        '200':
          description: >-
            Order note updated successfully. Returns true. Note will appear on
            all future recurring orders from this contract.
          content:
            application/json:
              schema:
                type: boolean
        '400':
          description: >-
            Bad request - contract doesn't belong to shop, note exceeds 5000
            characters, or contract in invalid state
          content:
            '*/*':
              schema:
                type: boolean
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                type: boolean
        '404':
          description: >-
            Subscription contract not found - ID doesn't exist, was deleted, or
            belongs to different shop
          content:
            '*/*':
              schema:
                type: boolean
  /api/external/v2/subscription-contracts-update-min-cycles:
    put:
      tags:
        - Membership Contracts
      summary: Update minimum billing cycles for subscription contract
      description: >-
        Sets the minimum number of billing cycles (payments) required before a
        customer can cancel their subscription. This is commonly used to enforce
        commitment periods or prevent early cancellations.


        **Key Features:**

        - **Commitment Enforcement**: Require customers to stay subscribed for a
        minimum period

        - **Cancellation Prevention**: Blocks cancellation until minimum cycles
        are met

        - **Contract Terms**: Implements contractual minimum billing
        requirements

        - **Flexible Duration**: Set any number from 0 (no minimum) to higher
        values


        **Common Use Cases:**

        - **3-Month Minimum**: Set minCycles=3 for quarterly commitment

        - **Annual Contract**: Set minCycles=12 for yearly subscriptions

        - **Trial Completion**: Require 1-2 cycles before allowing cancellation

        - **Remove Restriction**: Set minCycles=0 or null to remove minimum


        **Behavior:**

        - Customer portal will show "X cycles remaining until cancellation
        allowed"

        - Cancellation button disabled until minimum met

        - Does not affect pausing subscriptions

        - Applies to future billing cycles, not retroactive


        **Parameters:**

        - **contractId** (required): The subscription contract ID

        - **minCycles** (optional): Number of minimum cycles (null or 0 = no
        minimum)


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: updateMinCyclesV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 12345
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: minCycles
          in: query
          description: Minimum number of billing cycles required (null or 0 = no minimum)
          required: false
          schema:
            type: integer
            format: int32
          example: 3
      responses:
        '200':
          description: >-
            Min cycles updated successfully, returns updated subscription
            contract
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: Invalid request - contract not found or invalid parameters
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-contracts-update-max-cycles:
    put:
      tags:
        - Membership Contracts
      summary: Update maximum billing cycles for subscription contract
      description: >-
        Sets the maximum number of billing cycles (payments) after which the
        subscription will automatically expire and cancel. This is useful for
        creating fixed-term memberships or limited-duration subscriptions.


        **Key Features:**

        - **Auto-Expiration**: Subscription automatically cancels after max
        cycles reached

        - **Fixed-Term Plans**: Create memberships with defined end dates

        - **No Manual Intervention**: System handles cancellation automatically

        - **Flexible Duration**: Set any number or null for unlimited


        **Common Use Cases:**

        - **6-Month Program**: Set maxCycles=6 for half-year membership

        - **Annual Subscription**: Set maxCycles=12 for one-year auto-expiring
        plan

        - **Trial Extensions**: Set maxCycles=3 for limited trial periods

        - **Unlimited Subscription**: Set maxCycles=null or 0 for no maximum


        **Behavior:**

        - Subscription cancels automatically after final billing cycle

        - Customer receives notification before expiration

        - No refunds issued on auto-cancellation

        - Contract status changes to EXPIRED after last cycle


        **Parameters:**

        - **contractId** (required): The subscription contract ID

        - **maxCycles** (optional): Maximum number of billing cycles (null or 0
        = unlimited)


        **Note:** Setting maxCycles lower than current cycle count will cause
        immediate expiration.


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: updateMaxCyclesV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 12345
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: maxCycles
          in: query
          description: Maximum number of billing cycles (null or 0 = unlimited)
          required: false
          schema:
            type: integer
            format: int32
          example: 12
      responses:
        '200':
          description: >-
            Max cycles updated successfully, returns updated subscription
            contract
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: Invalid request - contract not found or invalid parameters
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-contracts-update-line-item:
    put:
      tags:
        - Membership Contracts
      summary: Update subscription line item quantity and pricing
      description: >-
        Updates an existing line item in a subscription contract, modifying
        quantity, variant, or price. This endpoint allows comprehensive updates
        to subscription products.


        **Line Item Update Process:**

        - **Line Item Identification**: Locates line item using GraphQL line ID

        - **Quantity Update**: Changes product quantity for recurring orders

        - **Variant Change**: Can switch to different variant of same product

        - **Price Override**: Optional custom pricing override

        - **Contract Sync**: Updates Shopify subscription contract

        - **Activity Logging**: Records line item modification event


        **Update Capabilities:**

        - **Quantity Adjustment**: Increase or decrease product quantity

        - **Variant Switching**: Change product variant (size, color, flavor,
        etc.)

        - **Custom Pricing**: Override standard pricing per line item

        - **Combined Updates**: Change multiple properties in single request


        **Parameters:**

        - **lineId**: GraphQL ID of line item to update

        - **quantity**: New quantity (must be positive integer)

        - **variantId**: Product variant ID (can change to different variant)

        - **price**: Custom price override (optional, overrides default pricing)


        **Price Override:**

        - Allows custom per-line pricing

        - Useful for special pricing arrangements

        - Overrides default product pricing

        - Price in shop's base currency


        **Use Cases:**

        - Customer increases/decreases product quantity

        - Switch product variant (e.g., Medium → Large roast)

        - Special pricing for VIP customers

        - Seasonal variant changes (Summer → Winter flavor)

        - Customer portal quantity adjustments

        - Wholesale pricing overrides

        - Build-a-box quantity modifications


        **Important Notes:**

        - Quantity must be positive (use remove-line-item to delete)

        - Variant must be valid and available

        - Price updates don't affect existing discount percentages

        - Changes apply to next billing cycle


        **Returns:** Updated subscription contract object with modified line
        item


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: updateLineItemV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 123456789
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: quantity
          in: query
          description: New quantity for the line item
          required: true
          schema:
            type: integer
            format: int32
          example: 3
        - name: variantId
          in: query
          description: Product variant ID (can be different variant)
          required: true
          schema:
            type: string
          example: 12345678
        - name: lineId
          in: query
          description: Line item GraphQL ID to update
          required: true
          schema:
            type: string
          example: gid://shopify/SubscriptionLine/987654321
        - name: price
          in: query
          description: Custom price override (optional)
          required: true
          schema:
            type: number
            format: double
          example: 29.99
      responses:
        '200':
          description: Line item successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: Invalid quantity, variant, or price
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract, line item, or variant not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '500':
          description: Shopify API error during line item update
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-contracts-update-line-item-attributes:
    put:
      tags:
        - Membership Contracts
      summary: Update custom attributes on subscription line item
      description: >-
        Updates custom attributes (metadata) on a specific subscription line
        item. Attributes allow storing custom key-value data on individual
        products in a subscription.


        **Attribute Update Process:**

        - **Line Item Identification**: Locates specific line item using GraphQL
        line ID

        - **Attribute Replacement**: Replaces existing attributes with new list

        - **Contract Update**: Syncs changes to Shopify subscription contract

        - **Activity Logging**: Records attribute modification event

        - **Freeze Validation**: Ensures subscription isn't frozen before
        updates


        **Custom Attributes:**

        - **Key-Value Pairs**: Store arbitrary metadata on line items

        - **Flexible Data**: Supports text, numbers, JSON as values

        - **Per-Item Storage**: Each line item has independent attributes

        - **Order Propagation**: Attributes carry forward to generated orders


        **Attribute Structure:**

        ```json

        [
          {"key": "gift_message", "value": "Happy Birthday!"},
          {"key": "custom_option", "value": "medium_roast"},
          {"key": "special_instructions", "value": "Leave at door"}
        ]

        ```


        **Line ID Format:**

        - GraphQL ID format: `gid://shopify/SubscriptionLine/[ID]`

        - Retrieve from subscription contract details endpoint

        - Each line item has unique ID


        **Use Cases:**

        - Store gift message customizations per product

        - Track product-specific preferences (roast level, flavor, size)

        - Custom delivery instructions for specific items

        - Personalization options (monogram, engraving text)

        - Build-a-box selection metadata

        - Product customization workflows

        - Integration data synchronization


        **Important Notes:**

        - Attributes are replaced, not merged (send all desired attributes)

        - Maximum 250 characters per value

        - Subscription must not be frozen

        - Attributes visible in Shopify admin and order details


        **Returns:** Updated subscription contract object with modified
        attributes


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: updateLineItemAttributesV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 123456789
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: lineId
          in: query
          description: Subscription line item GraphQL ID
          required: true
          schema:
            type: string
          example: gid://shopify/SubscriptionLine/987654321
      requestBody:
        description: List of custom attributes as key-value pairs
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/AttributeInfo'
        required: true
      responses:
        '200':
          description: Line item attributes successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: Invalid line ID, subscription frozen, or malformed attributes
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract or line item not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '500':
          description: Shopify API error during attribute update
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-contracts-update-delivery-interval:
    put:
      tags:
        - Subscription Contract Management
        - Membership Contracts
      summary: Update delivery interval for subscription contract
      description: >-
        Changes the delivery/shipping frequency of a subscription contract. This
        allows customers to modify how often they receive their subscription
        orders.


        **Key Features:**

        - **Flexible Delivery**: Change delivery frequency (daily, weekly,
        monthly, yearly)

        - **Custom Intervals**: Set custom interval counts (e.g., every 2 weeks,
        every 3 months)

        - **Independent from Billing**: Delivery interval can differ from
        billing interval

        - **Immediate Effect**: Changes apply to the next delivery cycle

        - **Activity Logging**: All changes are logged for audit trail


        **Delivery Interval Options:**

        - **DAY**: Daily delivery (intervalCount: how many days)

        - **WEEK**: Weekly delivery (intervalCount: how many weeks)

        - **MONTH**: Monthly delivery (intervalCount: how many months)

        - **YEAR**: Yearly delivery (intervalCount: how many years)


        **Common Examples:**

        - `intervalCount=1, interval=MONTH`: Deliver monthly

        - `intervalCount=2, interval=WEEK`: Deliver every 2 weeks

        - `intervalCount=3, interval=MONTH`: Deliver quarterly

        - `intervalCount=1, interval=WEEK`: Deliver weekly

        - `intervalCount=6, interval=MONTH`: Deliver twice a year


        **Billing vs. Delivery Intervals:**

        These can be different! For example:

        - **Bill monthly, deliver weekly**: Customer pays monthly but receives
        weekly shipments

        - **Bill quarterly, deliver monthly**: Customer pays every 3 months but
        receives monthly shipments

        - **Bill annually, deliver monthly**: Customer pays yearly upfront for
        monthly deliveries


        **Common Use Cases:**

        - Customer wants deliveries less frequently (save on shipping)

        - Customer wants deliveries more frequently (use products faster)

        - Adjust delivery to match consumption rate

        - Seasonal frequency changes (more in summer, less in winter)

        - Align deliveries with schedule (delivery when home from vacation)


        **Important Notes:**

        - **Billing Date Unchanged**: Only affects delivery schedule, not
        billing schedule

        - **Next Delivery Date**: System recalculates next delivery date based
        on new interval

        - **Order Fulfillment**: Each delivery creates a new order at the
        specified interval

        - **Prepaid Memberships**: Particularly useful for prepaid plans with
        multiple deliveries


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: updateDeliveryIntervalV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 12345
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: deliveryIntervalCount
          in: query
          description: Number of intervals between deliveries
          required: true
          schema:
            minimum: 1
            type: string
          example: 1
        - name: deliveryInterval
          in: query
          description: Delivery interval unit
          required: true
          schema:
            type: string
            enum:
              - DAY
              - WEEK
              - MONTH
              - YEAR
          example: MONTH
      responses:
        '200':
          description: Delivery interval successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: Invalid request - validation failed
          content:
            application/json:
              example:
                title: Bad Request
                status: 400
                detail: Invalid delivery interval or interval count
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '500':
          description: Shopify API error during delivery interval update
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-contracts-update-billing-interval:
    put:
      tags:
        - Subscription Contract Management
        - Membership Contracts
      summary: Update billing interval for subscription contract
      description: >-
        Changes the billing frequency of a subscription contract. This allows
        customers to modify how often they are charged for their membership.


        **Key Features:**

        - **Flexible Billing**: Change billing frequency (daily, weekly,
        monthly, yearly)

        - **Custom Intervals**: Set custom interval counts (e.g., every 2 weeks,
        every 3 months)

        - **Immediate Effect**: Changes apply to the next billing cycle

        - **Independent from Delivery**: Billing interval can differ from
        delivery interval

        - **Activity Logging**: All changes are logged for audit trail


        **Billing Interval Options:**

        - **DAY**: Daily billing (intervalCount: how many days)

        - **WEEK**: Weekly billing (intervalCount: how many weeks)

        - **MONTH**: Monthly billing (intervalCount: how many months)

        - **YEAR**: Yearly billing (intervalCount: how many years)


        **Common Examples:**

        - `intervalCount=1, interval=MONTH`: Bill monthly

        - `intervalCount=2, interval=WEEK`: Bill every 2 weeks

        - `intervalCount=3, interval=MONTH`: Bill quarterly

        - `intervalCount=6, interval=MONTH`: Bill semi-annually

        - `intervalCount=1, interval=YEAR`: Bill annually


        **Common Use Cases:**

        - Customer wants to change from monthly to quarterly billing

        - Switch from annual to monthly payments

        - Adjust billing frequency to match cash flow

        - Promotional frequency changes

        - Align billing with payday schedules


        **Important Notes:**

        - **Next Billing Date**: System recalculates the next billing date based
        on new interval

        - **Pro-rata Billing**: No pro-rata adjustment; new interval starts from
        next billing date

        - **Minimum Cycles**: Respects minimum billing cycle requirements if
        configured

        - **Customer Portal Protection**: Includes freeze checks if called from
        customer portal


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: updateBillingIntervalV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 12345
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: intervalCount
          in: query
          description: Number of intervals between billings
          required: true
          schema:
            minimum: 1
            type: string
          example: 1
        - name: interval
          in: query
          description: Billing interval unit
          required: true
          schema:
            type: string
            enum:
              - DAY
              - WEEK
              - MONTH
              - YEAR
          example: MONTH
      responses:
        '200':
          description: Billing interval successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: Invalid request - validation failed
          content:
            application/json:
              example:
                title: Bad Request
                status: 400
                detail: Invalid billing interval or interval count
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '403':
          description: Updates frozen until minimum billing cycles completed
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '500':
          description: Shopify API error during billing interval update
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-contracts-update-billing-date:
    put:
      tags:
        - Subscription Contract Management
        - Membership Contracts
      summary: Update subscription contract billing date
      description: >-
        Updates the next billing date for a subscription contract. This
        reschedules when the next payment will be charged for the membership.


        **Key Features:**

        - **Flexible Rescheduling**: Move billing date forward or backward

        - **Immediate Effect**: Changes take effect immediately in the billing
        schedule

        - **Automatic Adjustments**: Future billing dates recalculate based on
        frequency

        - **Customer Portal Compatible**: Can be triggered from customer
        self-service portal

        - **Activity Logging**: All changes are tracked in activity logs


        **Billing Date Update Rules:**

        - New date must be in the future (past dates are rejected)

        - Cannot update if contract is paused or cancelled

        - Cannot update if minimum billing cycles enforcement is active

        - Date format must be ISO 8601 with timezone (e.g.,
        2024-12-25T10:00:00Z)

        - Subsequent billing dates auto-calculate based on delivery frequency


        **Common Use Cases:**

        - Customer requests to postpone next delivery/billing

        - Align billing date with customer payday or preference

        - Skip a billing cycle due to vacation or temporary hold

        - Synchronize multiple subscriptions to bill on same day

        - Resolve payment timing conflicts or scheduling issues

        - Adjust for seasonal demand or customer availability


        **Important Notes:**

        - Changing billing date does NOT change the billing cycle frequency

        - If minimum cycles are configured, this may be restricted

        - Activity logs capture old date, new date, and change source

        - Customer receives updated billing schedule notification


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: updateNextBillingDateV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 12345
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: nextBillingDate
          in: query
          description: New next billing date in ISO 8601 format with timezone
          required: true
          schema:
            type: string
            format: date-time
          example: '2024-12-25T10:00:00Z'
      responses:
        '200':
          description: >-
            Billing date successfully updated, returns updated subscription
            contract
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: >-
            Invalid request - contract not found, date in past, or minimum
            cycles restriction active
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '403':
          description: >-
            Forbidden - contract does not belong to authenticated shop or update
            not allowed
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-contracts-remove-line-item:
    put:
      tags:
        - Membership Contracts
      summary: Remove product from recurring subscription
      description: >-
        Removes a line item (product) from a subscription contract. The product
        will no longer be included in future recurring orders.


        **Product Removal Process:**

        - **Line Item Identification**: Locates specific line item using GraphQL
        line ID

        - **Contract Update**: Removes line item from subscription

        - **Discount Handling**: Optionally removes associated line-item
        discounts

        - **Price Recalculation**: Updates subscription total after removal

        - **Activity Logging**: Records product removal event


        **Key Features:**

        - **Selective Removal**: Remove specific products by line ID

        - **Discount Control**: Choose whether to remove product-specific
        discounts

        - **Immediate Effect**: Changes apply to next billing cycle

        - **Price Updates**: Automatically adjusts subscription pricing


        **Discount Removal Option:**

        - **removeDiscount=true** (default): Removes discounts tied to this line
        item

        - **removeDiscount=false**: Keeps discounts (may apply to other items if
        applicable)

        - Only affects line-item-specific discounts, not subscription-level
        discounts


        **Line ID Format:**

        - GraphQL ID format: `gid://shopify/SubscriptionLine/[ID]`

        - Retrieve from subscription contract details endpoint

        - Each line item has unique ID


        **Use Cases:**

        - Customer downgrades subscription to fewer products

        - Remove seasonal products at end of season

        - Customer portal product removal workflows

        - Discontinued product cleanup

        - Subscription simplification (too many items)

        - Build-a-box customization changes


        **Important Notes:**

        - Cannot remove last line item (subscription needs at least one product)

        - Subscription must not be frozen

        - Removal is permanent (re-add if needed)

        - May affect shipping costs if weight/volume changes


        **Returns:** Updated subscription contract object with line item removed


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: removeLineItemV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 123456789
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: lineId
          in: query
          description: Subscription line item GraphQL ID to remove
          required: true
          schema:
            type: string
          example: gid://shopify/SubscriptionLine/987654321
        - name: removeDiscount
          in: query
          description: 'Whether to remove associated line-item discounts (default: true)'
          required: false
          schema:
            type: boolean
            default: true
          example: true
      responses:
        '200':
          description: Line item successfully removed from subscription
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: Cannot remove last line item or subscription is frozen
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract or line item not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '500':
          description: Shopify API error during line item removal
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-contracts-remove-discount:
    put:
      tags:
        - Membership Contracts
      summary: Remove discount from subscription
      description: >-
        Removes a discount from a subscription contract. This endpoint allows
        you to remove previously applied discounts, restoring the subscription
        to full price.


        **Discount Removal Process:**

        - **Identify Discount**: Uses discount ID to locate specific discount on
        contract

        - **Remove From Contract**: Removes discount allocation from
        subscription

        - **Recalculate Pricing**: Updates subscription pricing to remove
        discount

        - **Activity Logging**: Records discount removal event

        - **Immediate Effect**: Changes apply to next billing cycle


        **Key Features:**

        - **Selective Removal**: Remove specific discounts by ID

        - **Price Restoration**: Returns subscription to original or remaining
        discount pricing

        - **Multiple Discount Support**: Works with subscriptions having
        multiple discounts

        - **Activity Tracking**: Logs removal for audit trail


        **Finding Discount ID:**

        - Retrieve subscription contract details to see applied discounts

        - Each discount has a unique Shopify GraphQL ID

        - Format: `gid://shopify/SubscriptionManualDiscount/[ID]`


        **Use Cases:**

        - End limited-time promotional discounts

        - Remove expired retention offers

        - Customer service discount adjustments

        - Clean up incorrectly applied discounts

        - Remove trial period pricing

        - End referral program bonuses


        **Returns:** Updated subscription contract object with discount removed


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: removeDiscountV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID to remove discount from
          required: true
          schema:
            type: integer
            format: int64
          example: 123456789
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: discountId
          in: query
          description: Shopify discount ID to remove (GraphQL ID format)
          required: true
          schema:
            type: string
          example: gid://shopify/SubscriptionManualDiscount/123456789
      responses:
        '200':
          description: Discount successfully removed from subscription
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: Invalid discount ID or discount not found on contract
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '500':
          description: Shopify API error during discount removal
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-contracts-apply-discount:
    put:
      tags:
        - Membership Contracts
      summary: Apply discount code to subscription
      description: >-
        Applies an existing Shopify discount code to a subscription contract.
        The discount code must already exist in Shopify and be valid for
        subscription usage.


        **Discount Application Process:**

        - **Code Validation**: Verifies discount code exists in Shopify

        - **Eligibility Check**: Ensures code is valid for subscription use

        - **Contract Update**: Applies discount to subscription contract

        - **Price Recalculation**: Updates subscription pricing with discount
        applied

        - **Activity Logging**: Records discount application event


        **Key Features:**

        - **Existing Code Support**: Uses Shopify discount codes already created
        in admin

        - **Automatic Validation**: Checks code validity and subscription
        eligibility

        - **Immediate Application**: Discount applies to next billing cycle

        - **Contract Synchronization**: Keeps Shopify contract in sync with
        discount


        **Discount Code Requirements:**

        - Must exist in Shopify admin

        - Must be active and not expired

        - Must be eligible for subscription purchases

        - Usage limits must not be exceeded


        **Use Cases:**

        - Allow customers to apply promotional codes to existing subscriptions

        - Customer service applying retention discounts

        - Reward program integration with discount codes

        - Referral program discount application

        - Seasonal promotion code application

        - Win-back campaign discount codes


        **Returns:** Updated subscription contract object with discount applied


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: applyDiscountCodeV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID to apply discount to
          required: true
          schema:
            type: integer
            format: int64
          example: 123456789
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: discountCode
          in: query
          description: Shopify discount code to apply
          required: true
          schema:
            type: string
          example: SUMMER2024
      responses:
        '200':
          description: Discount code successfully applied to subscription
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: Invalid discount code or not eligible for subscriptions
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract or discount code not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '500':
          description: Shopify API error during discount application
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-contracts-add-line-item:
    put:
      tags:
        - Membership Contracts
      summary: Add product to recurring subscription
      description: >-
        Adds a new product variant to a subscription contract's recurring line
        items. The product will be included in all future recurring orders.


        **Product Addition Process:**

        - **Variant Validation**: Verifies product variant exists and is
        available

        - **Add to Contract**: Adds line item to subscription's recurring
        products

        - **Quantity Setting**: Sets initial quantity for the product

        - **Price Calculation**: Calculates pricing including any applicable
        discounts

        - **Shipping Update**: May recalculate shipping if weight/dimensions
        change

        - **Activity Logging**: Records product addition event


        **Key Features:**

        - **Recurring Addition**: Product added to every future order

        - **Quantity Control**: Specify exact quantity to add

        - **Discount Inheritance**: New item inherits subscription-level
        discounts

        - **Immediate Effect**: Applies to next billing cycle

        - **Freeze Protection**: Validates subscription isn't frozen before
        minimum cycles


        **Variant ID Format:**

        - Accepts Shopify variant ID as string

        - Can be numeric ID or GraphQL format

        - Example: "12345678" or "gid://shopify/ProductVariant/12345678"


        **Use Cases:**

        - Customer upgrades subscription to include more products

        - Cross-sell additional products to existing subscribers

        - Allow customers to customize subscriptions in portal

        - Add seasonal products to subscriptions

        - Build-a-box subscription customization

        - Upsell workflows during customer interactions


        **Important Notes:**

        - Product must be available for purchase

        - Subscription must not be frozen (before min cycles)

        - Price updates automatically with subscription billing

        - Quantity must be positive integer


        **Returns:** Updated subscription contract object with new line item


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: addLineItemV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID to add product to
          required: true
          schema:
            type: integer
            format: int64
          example: 123456789
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: quantity
          in: query
          description: Quantity of the product to add
          required: true
          schema:
            type: integer
            format: int32
          example: 2
        - name: variantId
          in: query
          description: Shopify product variant ID
          required: true
          schema:
            type: string
          example: 12345678
      responses:
        '200':
          description: Product successfully added to subscription
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: Invalid variant ID, subscription frozen, or product not available
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract or product variant not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '500':
          description: Shopify API error during line item addition
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-contracts-add-discount:
    put:
      tags:
        - Membership Contracts
      summary: Create and add custom discount to subscription
      description: >-
        Creates a custom discount and applies it to a subscription contract.
        This endpoint allows you to create on-the-fly discounts without
        requiring pre-existing discount codes in Shopify.


        **Discount Creation & Application:**

        - **Custom Discount**: Creates discount directly on subscription
        contract

        - **Flexible Types**: Supports percentage off or fixed amount off

        - **Cycle Limits**: Optional limit on number of billing cycles discount
        applies

        - **Item-Level Control**: Option to apply discount to each item vs
        entire order

        - **Immediate Effect**: Discount applies to next billing cycle


        **Discount Parameters:**

        - **Percentage**: Percentage discount (e.g., 15 for 15% off) - use for
        discountType='PERCENTAGE'

        - **Amount**: Fixed amount discount (e.g., 10.00 for $10 off) - use for
        discountType='FIXED_AMOUNT'

        - **Title**: Display name for the discount (e.g., 'Loyalty Discount')

        - **Cycle Limit**: Number of billing cycles discount applies (null =
        unlimited)

        - **Applies On Each Item**: true = per-item discount, false =
        order-level discount


        **Discount Types:**

        - **PERCENTAGE**: Percentage-based discount (use 'percentage' parameter)

        - **FIXED_AMOUNT**: Fixed dollar amount discount (use 'amount'
        parameter)


        **Cycle Limit Examples:**

        - `recurringCycleLimit=1`: Discount for first order only

        - `recurringCycleLimit=3`: Discount for first 3 orders

        - `recurringCycleLimit=null`: Discount applies forever


        **Use Cases:**

        - Customer retention offers (e.g., 20% off next 3 orders)

        - Loyalty rewards and point redemptions

        - Win-back campaigns with limited-time discounts

        - Customer service compensation discounts

        - Referral program rewards

        - First-order discounts for new subscribers

        - Seasonal promotions on existing subscriptions


        **Example Scenarios:**

        1. **Retention Offer**: 25% off for 2 billing cycles
           - percentage=25, recurringCycleLimit=2, discountType='PERCENTAGE'
        2. **Loyalty Reward**: $5 off every order forever
           - amount=5.00, recurringCycleLimit=null, discountType='FIXED_AMOUNT'
        3. **First Order Deal**: 50% off first order only
           - percentage=50, recurringCycleLimit=1, discountType='PERCENTAGE'

        **Returns:** Updated subscription contract object with discount applied


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: addDiscountV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID to add discount to
          required: true
          schema:
            type: integer
            format: int64
          example: 123456789
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: percentage
          in: query
          description: Percentage discount value (use with discountType=PERCENTAGE)
          required: false
          schema:
            type: integer
            format: int32
          example: 15
        - name: discountTitle
          in: query
          description: Display title for the discount
          required: false
          schema:
            type: string
          example: Loyalty Discount
        - name: recurringCycleLimit
          in: query
          description: Number of billing cycles discount applies (null for unlimited)
          required: false
          schema:
            type: integer
            format: int32
          example: 3
        - name: appliesOnEachItem
          in: query
          description: >-
            Apply discount to each item individually (true) or entire order
            (false)
          required: false
          schema:
            type: boolean
          example: false
        - name: amount
          in: query
          description: Fixed amount discount value (use with discountType=FIXED_AMOUNT)
          required: false
          schema:
            type: number
            format: double
          example: 10
        - name: discountType
          in: query
          description: 'Discount type: PERCENTAGE or FIXED_AMOUNT'
          required: false
          schema:
            type: string
          example: PERCENTAGE
      responses:
        '200':
          description: Discount successfully created and applied to subscription
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: >-
            Invalid discount parameters (missing percentage/amount, invalid
            type, etc.)
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '500':
          description: Shopify API error during discount creation
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-contract-update-variant:
    put:
      tags:
        - Subscription Contract Management
        - Membership Contracts
      summary: Update product variant in subscription contract
      description: >-
        Replaces an existing product variant with a new variant in a
        subscription contract. This allows customers to swap products in their
        membership while maintaining their subscription.


        **Key Features:**

        - **Product Swapping**: Replace any line item's variant with a different
        variant

        - **Quantity Preservation**: Maintains the same quantity after variant
        swap

        - **Price Updates**: New variant pricing is applied automatically

        - **Flexible Identification**: Identify old variant by lineId OR
        variantId

        - **Activity Logging**: All variant changes are logged for audit trail


        **Identification Methods:**

        You can identify the old variant using either:

        - **oldLineId**: The Shopify line item ID from the subscription contract

        - **oldVariantId**: The Shopify product variant ID

        At least one of these must be provided.


        **Common Use Cases:**

        - Customer wants to change product flavor/color/size in their membership

        - Swap discontinued products with new alternatives

        - Change product preferences mid-subscription

        - Update seasonal product selections

        - Replace out-of-stock variants with alternatives


        **Important Notes:**

        - **Immediate Effect**: Variant change applies to the next billing cycle

        - **Validation**: System validates new variant exists and is available

        - **Same Product**: Old and new variants can be from different products

        - **Price Changes**: Customer is charged the new variant's price


        **Variant ID Format:**

        - Accepts both numeric IDs and GraphQL IDs
        (gid://shopify/ProductVariant/...)

        - System automatically converts to correct format


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: updateVariantV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 12345
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: oldLineId
          in: query
          description: Line item ID to replace (provide either oldLineId or oldVariantId)
          required: false
          schema:
            type: string
          example: gid://shopify/SubscriptionLine/123
        - name: oldVariantId
          in: query
          description: Old variant ID to replace (provide either oldLineId or oldVariantId)
          required: false
          schema:
            type: string
          example: 40123456789
        - name: newVariantId
          in: query
          description: New variant ID to use as replacement
          required: true
          schema:
            type: string
          example: 40987654321
        - name: skipBilling
          in: query
          description: Skip billing on plan change (no charge or refund)
          required: false
          schema:
            type: boolean
            default: false
          example: false
      responses:
        '200':
          description: Variant successfully updated in subscription contract
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: Invalid request - validation failed
          content:
            application/json:
              examples:
                Same variant error:
                  description: Same variant error
                  value:
                    title: Bad Request
                    status: 400
                    detail: >-
                      UserGeneratedError:New variant cannot be the same as old
                      variant
                Missing old variant:
                  description: Missing old variant
                  value:
                    title: Bad Request
                    status: 400
                    detail: 'UserGeneratedError: Old variant not provided'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract or variant not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '500':
          description: Shopify API error during variant update
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-contract-one-offs-by-contractId-and-billing-attempt-id:
    put:
      tags:
        - One-Time Add-Ons
      summary: Add one-time product to upcoming order
      description: >-
        Adds a one-time product (one-off) to a specific upcoming billing attempt
        for a membership contract. The product will be included only in the
        specified order and will not become part of the recurring subscription.


        **Key Features:**

        - **One-Time Addition**: Product added to single order only

        - **Billing Cycle Targeting**: Specify exact order to add item to

        - **No Subscription Impact**: Doesn't change recurring items

        - **Instant Upsell**: Add products between regular billing cycles

        - **Customer Flexibility**: Allow members to add extras to next order

        - **Activity Logging**: Tracks who added the item (merchant vs API)


        **Required Parameters:**

        - **Contract ID**: Target subscription contract

        - **Billing Attempt ID**: Specific upcoming order to add item to

        - **Variant ID**: Shopify product variant to add

        - **Variant Handle**: Product handle for identification


        **How It Works:**

        1. Validates contract exists and belongs to shop

        2. Checks if contract is not frozen (minimum cycles)

        3. Verifies billing attempt is upcoming (not already processed)

        4. Adds variant to the specified billing attempt

        5. Returns updated list of all one-offs for the contract

        6. Logs activity for audit trail


        **Use Cases:**

        - Customer wants to add a bonus product to next delivery

        - Merchant offers limited-time add-on to existing members

        - Trial/sample products added to specific orders

        - Holiday specials or seasonal items

        - Promotional gifts or rewards

        - One-time upsells in customer portal


        **Business Rules:**

        - Item added only to specified billing attempt

        - Cannot add to past or completed orders

        - Contract must not be frozen/minimum cycle locked

        - Duplicate items increment quantity


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: saveOneOffByV2
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 123456
        - name: billingAttemptId
          in: query
          description: Billing attempt ID to add the item to
          required: true
          schema:
            type: integer
            format: int64
          example: 789012
        - name: variantId
          in: query
          description: Product variant ID to add
          required: true
          schema:
            type: integer
            format: int64
          example: 456789
        - name: variantHandle
          in: query
          description: Product handle for identification
          required: true
          schema:
            type: string
          example: coffee-beans-1lb
      responses:
        '200':
          description: >-
            One-off product successfully added, returns updated list of all
            one-offs
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractOneOffDTO'
        '400':
          description: Invalid request or business rule violation
          content:
            application/json:
              examples:
                Frozen Contract:
                  description: Frozen Contract
                  value:
                    title: Bad Request
                    status: 400
                    detail: >-
                      Cannot modify contract frozen until minimum cycles
                      completed
                    errorKey: frozen_contract
                Invalid Billing Attempt:
                  description: Invalid Billing Attempt
                  value:
                    title: Bad Request
                    status: 400
                    detail: Billing attempt not found or already processed
                    errorKey: invalid_billing_attempt
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractOneOffDTO'
        '403':
          description: Access forbidden - contract does not belong to authenticated shop
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractOneOffDTO'
        '404':
          description: Contract or variant not found
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractOneOffDTO'
    delete:
      tags:
        - One-Time Add-Ons
      summary: Remove one-time product from upcoming order
      description: >-
        Removes a previously added one-time product (one-off) from a specific
        upcoming billing attempt. This allows customers or merchants to cancel
        add-on items before the order is processed.


        **Key Features:**

        - **Flexible Cancellation**: Remove add-ons before order processes

        - **Targeted Removal**: Remove specific variant from specific order

        - **No Subscription Impact**: Doesn't affect recurring items

        - **Customer Control**: Let members manage their add-ons

        - **Activity Logging**: Tracks removal for audit trail


        **Required Parameters:**

        - **Contract ID**: Target subscription contract

        - **Billing Attempt ID**: Order to remove item from

        - **Variant ID**: Product variant to remove


        **How It Works:**

        1. Validates contract exists and belongs to shop

        2. Finds one-off matching contract, billing attempt, and variant

        3. Deletes the one-off record

        4. Returns updated list of remaining one-offs

        5. Logs removal activity for audit trail


        **Use Cases:**

        - Customer changes mind about add-on product

        - Remove out-of-stock items from upcoming orders

        - Cancel promotional items no longer available

        - Customer wants to reduce order total

        - Merchant corrects mistakenly added items

        - Manage add-ons in customer portal


        **Business Rules:**

        - Can only remove from upcoming (unprocessed) orders

        - Must match exact contract, billing attempt, and variant

        - Returns remaining one-offs after deletion

        - Cannot remove from past/completed orders


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: deleteOneOff
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 123456
        - name: billingAttemptId
          in: query
          description: Billing attempt ID to remove the item from
          required: true
          schema:
            type: integer
            format: int64
          example: 789012
        - name: variantId
          in: query
          description: Product variant ID to remove
          required: true
          schema:
            type: integer
            format: int64
          example: 456789
      responses:
        '200':
          description: >-
            One-off product successfully removed, returns updated list of
            remaining one-offs
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractOneOffDTO'
        '400':
          description: Invalid request or item not found
          content:
            application/json:
              example:
                title: Bad Request
                status: 400
                detail: One-off item not found or already processed
                errorKey: not_found
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractOneOffDTO'
        '403':
          description: Access forbidden - contract does not belong to authenticated shop
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractOneOffDTO'
        '404':
          description: Contract or one-off item not found
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractOneOffDTO'
  /api/external/v2/subscription-contract-add-line-item:
    put:
      tags:
        - Subscription Contract Management
        - Membership Contracts
      summary: Add product line item to subscription contract
      description: >-
        Adds a new product (line item) to an existing subscription contract.
        This allows customers or merchants to add products to their recurring
        subscription orders.


        **Key Features:**

        - **Add Products**: Include new products in future subscription
        deliveries

        - **Quantity Control**: Specify how many units of the product to add

        - **Price Override**: Set custom pricing for the added product

        - **Immediate Effect**: Changes apply to next billing cycle

        - **Activity Logging**: All additions are tracked in activity logs


        **Required Parameters:**

        - **contractId**: Subscription contract ID to modify

        - **variantId**: Shopify product variant ID (with gid:// prefix or
        numeric)

        - **quantity**: Number of units to add (must be positive integer)

        - **price**: Price per unit in shop's base currency


        **Product Variant ID Format:**

        Accepts two formats:

        - Shopify GID: `gid://shopify/ProductVariant/12345678901`

        - Numeric ID: `12345678901`


        **Price Behavior:**

        - Price is per unit, not total

        - Must be in shop's base currency (USD, EUR, etc.)

        - Can override product's default price

        - Does not include taxes or shipping

        - Total line item cost = price × quantity


        **Line Item Addition Rules:**

        - Product variant must exist in Shopify catalog

        - Product must be active and available

        - Variant must have sufficient inventory (if tracked)

        - Contract must be ACTIVE or PAUSED (not CANCELLED)

        - Cannot add duplicate variants (use update quantity instead)


        **Common Use Cases:**

        - Customer adds complementary product to existing subscription

        - Upsell additional products through customer portal

        - Merchant adds bonus items to customer subscriptions

        - Build custom "add-on" product selection interfaces

        - Cross-sell related products to existing subscribers

        - Create bundle upgrades (add multiple products at once)


        **Post-Addition Effects:**

        - Next billing amount increases by (price × quantity)

        - Product appears in all future subscription deliveries

        - Customer receives confirmation of subscription update

        - Activity log records the addition with source (portal/merchant)

        - Contract's next billing date remains unchanged


        **Integration Example:**

        ```

        PUT /api/external/v2/subscription-contract-add-line-item?
          contractId=123456&
          variantId=gid://shopify/ProductVariant/987654321&
          quantity=2&
          price=19.99
        ```

        This adds 2 units of variant 987654321 at $19.99 each ($39.98 total) to
        contract 123456.


        **Important Notes:**

        - Changes apply to NEXT billing cycle, not current/past orders

        - If product is out of stock, order may be delayed or skipped

        - Price changes don't affect historical orders

        - Consider inventory availability before adding products


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: addLineItemV2_1
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 12345
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: quantity
          in: query
          description: Quantity of product to add
          required: true
          schema:
            type: integer
            format: int32
          example: 2
        - name: variantId
          in: query
          description: Shopify product variant ID (with or without gid:// prefix)
          required: true
          schema:
            type: string
          example: gid://shopify/ProductVariant/987654321
        - name: price
          in: query
          description: Price per unit in shop's base currency
          required: true
          schema:
            type: number
            format: double
          example: 19.99
      responses:
        '200':
          description: Line item successfully added to subscription contract
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: >-
            Invalid request - product not found, contract cancelled, or
            duplicate variant
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '403':
          description: Forbidden - contract does not belong to authenticated shop
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract or product variant not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-bundlings/discount/{token}:
    put:
      tags:
        - Product Bundles
      summary: Generate bundle-specific discount code
      description: >-
        Creates a Shopify discount code specifically for a subscription bundle.
        This endpoint generates unique, single-use or multi-use discount codes
        tied to bundle purchases.


        **Key Features:**

        - **Bundle-Specific Codes**: Discounts that apply only to specific
        bundles

        - **Flexible Discount Types**: Percentage off, fixed amount off, or free
        shipping

        - **Usage Limits**: Single-use, limited use, or unlimited codes

        - **Expiration Dates**: Set validity periods for promotional campaigns

        - **Minimum Requirements**: Minimum purchase amount or quantity
        thresholds

        - **Customer Eligibility**: Restrict to specific customer segments or
        tags


        **Discount Configuration:**

        - **Code Format**: Custom code or auto-generated random code

        - **Discount Value**: Percentage (e.g., 15%) or fixed amount (e.g., $10)

        - **Start/End Dates**: Campaign duration controls

        - **Usage Limit**: Max number of times code can be used

        - **Once Per Customer**: Prevent code reuse by same customer

        - **Bundle Association**: Links discount to specific bundle token


        **Use Cases:**

        - Create promotional codes for bundle launches

        - Generate unique codes for influencer campaigns

        - Offer first-time subscriber discounts on bundles

        - Seasonal or holiday bundle promotions

        - Referral program discount codes

        - Partner/affiliate exclusive bundle offers


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: generateDiscountV2
      parameters:
        - name: token
          in: path
          description: Bundle token identifier
          required: true
          schema:
            type: string
          example: abc123xyz
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      requestBody:
        description: Discount code configuration including code, value, type, and validity
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DiscountCodeRequest'
        required: true
      responses:
        '200':
          description: Discount code successfully created in Shopify
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DiscountCodeResponse'
        '400':
          description: Invalid discount configuration
          content:
            application/json:
              example:
                title: Bad Request
                status: 400
                detail: Invalid discount code format or configuration
                errorKey: validation_error
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/DiscountCodeResponse'
        '404':
          description: Bundle not found with specified token
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/DiscountCodeResponse'
        '500':
          description: Shopify API error during discount code creation
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/DiscountCodeResponse'
  /api/external/v2/subscription-billing-attempts:
    put:
      tags:
        - Billing & Orders
        - Subscription Billing
      summary: Update subscription billing attempt
      description: >-
        Updates billing attempt details for a subscription contract. Billing
        attempts represent individual charge attempts for recurring subscription
        orders.


        **Key Information Updated:**

        - **Billing Date**: Next scheduled billing/charge date

        - **Status**: Success, failed, pending, or scheduled

        - **Error Messages**: Failure reasons for declined payments

        - **Retry Count**: Number of retry attempts made

        - **Order ID**: Associated Shopify order if billing succeeded

        - **Amount**: Billing amount charged or attempted


        **Billing Attempt Lifecycle:**

        1. **Scheduled**: Billing attempt is queued for future processing

        2. **Pending**: Charge is being processed by payment gateway

        3. **Success**: Payment captured, order created

        4. **Failed**: Payment declined or error occurred

        5. **Retrying**: Automatic retry scheduled after failure


        **Common Use Cases:**

        - Reschedule failed billing attempts to a new date

        - Update billing date to align with customer preferences

        - Mark manual payment reconciliation in external systems

        - Sync billing status with external payment processors

        - Trigger retry logic for failed payment attempts

        - Update billing metadata for reporting and analytics


        **Important Notes:**

        - Changing billing date will affect the subscription's billing cycle

        - Only pending or failed attempts can typically be modified

        - Successfully billed attempts are immutable in most cases


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: updateSubscriptionBillingAttemptV2
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      requestBody:
        description: >-
          Updated billing attempt details including billing date, status, and
          metadata
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubscriptionBillingAttemptDTO'
        required: true
      responses:
        '200':
          description: Billing attempt successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionBillingAttemptDTO'
        '400':
          description: >-
            Invalid request - validation failed or billing attempt cannot be
            modified
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionBillingAttemptDTO'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionBillingAttemptDTO'
        '404':
          description: Billing attempt not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionBillingAttemptDTO'
  /api/external/v2/subscription-billing-attempts/skip-order/{id}:
    put:
      tags:
        - Billing & Orders
        - Subscription Billing
      summary: Skip upcoming subscription order
      description: >-
        Skips a scheduled billing attempt, preventing the order from being
        processed. The next billing date is automatically recalculated based on
        the subscription frequency.


        **Key Features:**

        - **Flexible Skipping**: Skip any upcoming order

        - **Auto-Rescheduling**: Next billing date automatically adjusted

        - **Prepaid Support**: Handles both regular and prepaid subscriptions

        - **Activity Logging**: Tracks skip events for reporting

        - **Customer Control**: Allow members to manage delivery timing


        **How It Works:**

        1. Marks the billing attempt as skipped

        2. Calculates new next billing date (current date + frequency)

        3. Updates subscription contract in Shopify

        4. Logs skip activity with event source

        5. Returns updated billing attempt details


        **Use Cases:**

        - Customer going on vacation

        - Too much inventory on hand

        - Temporary pause without canceling

        - Budget constraints for specific month

        - Customize delivery schedule


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: skipOrderV2
      parameters:
        - name: id
          in: path
          description: Billing attempt ID to skip
          required: true
          schema:
            type: integer
            format: int64
          example: 123456
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: subscriptionContractId
          in: query
          description: Subscription contract ID
          required: false
          schema:
            type: integer
            format: int64
          example: 789012
        - name: isPrepaid
          in: query
          description: Whether this is a prepaid subscription
          required: false
          schema:
            type: boolean
            default: false
          example: false
      responses:
        '200':
          description: Order successfully skipped, returns updated billing attempt
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionBillingAttemptDTO'
        '400':
          description: Cannot skip - order already processed or invalid state
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionBillingAttemptDTO'
        '401':
          description: Authentication required
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionBillingAttemptDTO'
        '404':
          description: Billing attempt or contract not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionBillingAttemptDTO'
  /api/external/v2/subscription-billing-attempts/attempt-billing/{id}:
    put:
      tags:
        - Billing & Orders
        - Subscription Billing
      summary: Retry billing for failed attempt
      description: >-
        Immediately triggers a billing attempt for a subscription contract,
        bypassing the normal scheduled billing time. This endpoint processes the
        billing asynchronously via Shopify's Subscription Billing API, creating
        an order and charging the customer's payment method.


        **How Billing Retry Works:**

        1. **Validation**: Checks if shop has `enableImmediatePlaceOrder`
        permission (premium feature)

        2. **Async Trigger**: Queues billing job in background (returns
        immediately)

        3. **Shopify API Call**: Sends `subscriptionBillingAttemptCreate`
        mutation to Shopify

        4. **Payment Processing**: Charges customer's stored payment method

        5. **Order Creation**: Creates Shopify order if payment succeeds

        6. **Notification**: Sends order confirmation email to customer (if
        enabled)

        7. **Webhook Events**: Triggers `SUBSCRIPTION_BILLING_ATTEMPTS_SUCCESS`
        or `_FAILURE` webhook


        **When to Use This Endpoint:**

        - **Payment Failed Previously**: Customer updated credit card, retry
        failed billing

        - **Scheduled Too Far Out**: Customer wants early delivery, bill before
        scheduled date

        - **Payment Method Updated**: Customer just added new payment method,
        retry immediately

        - **Manual Recovery**: Merchant intervention to recover failed
        subscription

        - **Testing/QA**: Validate subscription billing flow in test
        environments

        - **Customer Request**: Expedited order fulfillment for urgent needs


        **Important Limitations & Restrictions:**

        - **Permission Required**: Only available to shops with
        `enableImmediatePlaceOrder` permission
          - This is a premium feature - free plans will receive 400 error
          - Upgrade subscription plan in Appstle admin to enable
        - **Rate Limiting**: Maximum 5 billing attempts per contract per hour
        (anti-abuse)

        - **Billing Attempt Status**: Can retry attempts with status `QUEUED`,
        `SCHEDULED`, or `FAILED`

        - **Cannot Retry**: Billing attempts with status `SUCCESS` (order
        already created)

        - **Duplicate Prevention**: Shopify prevents duplicate orders within
        24-hour window

        - **Payment Method Required**: Contract must have valid payment method
        attached


        **Asynchronous Processing Details:**

        This endpoint returns **immediately** (200 OK) before billing completes.
        Actual billing happens in background:

        - **Success Response**: Means billing job was queued, NOT that payment
        succeeded

        - **Actual Result**: Check via webhooks or poll
        `/subscription-billing-attempts` endpoint

        - **Processing Time**: Typically 5-30 seconds depending on Shopify API
        response time

        - **Timeout Handling**: Background job retries up to 3 times if Shopify
        API times out


        **Checking Billing Result (Recommended Flow):**

        ```

        Step 1: Call this endpoint to trigger billing
          PUT /subscription-billing-attempts/attempt-billing/123456
          Response: 200 OK (billing queued)

        Step 2: Wait 10-15 seconds for processing


        Step 3: Poll billing attempt status
          GET /subscription-billing-attempts?id=123456
          Check 'status' field:
          - SUCCESS: Order created, payment captured
          - FAILED: Payment declined or error occurred
          - PROCESSING: Still in progress, poll again

        Step 4: (Alternative) Use webhooks for real-time updates
          Configure webhook: SUBSCRIPTION_BILLING_ATTEMPTS_SUCCESS
          Receive notification when billing completes
        ```


        **Common Error Scenarios:**

        - **400 - Permission Denied**: "You don't have permission to place
        immediate orders"
          - **Solution**: Upgrade to premium plan with `enableImmediatePlaceOrder` feature
        - **400 - Rate Limit**: "Too many billing attempts. Maximum 5 per hour
        per contract."
          - **Solution**: Wait before retrying, investigate why billing keeps failing
        - **400 - Invalid Status**: "Cannot retry billing attempt with status
        SUCCESS"
          - **Solution**: Order already created successfully, check order history
        - **404 - Not Found**: "Billing attempt not found"
          - **Solution**: Verify billing attempt ID belongs to this shop
        - **500 - Shopify API Error**: Background job may fail if Shopify API is
        down
          - **Solution**: Retry after 5 minutes, check Shopify status page

        **Payment Failure Reasons (Check After Async Processing):**

        After billing processes, if status becomes `FAILED`, common reasons
        include:

        - **Card Declined**: Insufficient funds, expired card, fraud detection

        - **Invalid Payment Method**: Customer deleted payment method

        - **3D Secure Failed**: Authentication challenge not completed

        - **Gateway Error**: Payment processor (Stripe/Shopify Payments) issue

        - **Inventory Shortage**: Product out of stock, cannot fulfill order

        - **Subscription Canceled**: Contract canceled between retry trigger and
        processing


        **Integration Best Practices:**

        1. **Always Check Permission First**: Call `/shop-info` or similar to
        verify feature access

        2. **Implement Webhooks**: Don't rely on polling - use webhooks for
        real-time status

        3. **User Communication**: Warn user "Billing in progress..." since it's
        async

        4. **Idempotency**: Safe to call multiple times - Shopify prevents
        duplicate orders

        5. **Error Handling**: Gracefully handle permission errors for free plan
        users

        6. **Logging**: Track billing attempt ID for troubleshooting and support


        **Example Use Case - Customer Portal:**

        ```

        Scenario: Customer's card declined, they updated payment method


        1. Customer sees "Payment Failed" in portal

        2. Customer clicks "Update Payment Method" → adds new card

        3. Customer clicks "Retry Payment Now" button

        4. Frontend calls: PUT
        /subscription-billing-attempts/attempt-billing/789

        5. Display: "Processing payment..." spinner

        6. Poll endpoint every 5 seconds for status update

        7. On SUCCESS: Show "Payment successful! Order #12345 created."

        8. On FAILED: Show decline reason + retry instructions

        ```


        **Difference from Skip/Reschedule:**

        - **Attempt Billing**: Immediately charges customer and creates order
        NOW

        - **Skip**: Postpones order to next billing cycle, no charge

        - **Reschedule**: Changes billing date without triggering immediate
        charge


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter. Additionally requires merchant account to have
        `enableImmediatePlaceOrder` permission (premium feature).
      operationId: attemptBillingV2
      parameters:
        - name: id
          in: path
          description: Billing attempt ID to retry
          required: true
          schema:
            type: integer
            format: int64
          example: 123456
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      responses:
        '200':
          description: >-
            Billing attempt successfully queued for asynchronous processing.
            This does NOT mean payment succeeded - billing happens in
            background. Poll the billing attempt status or use webhooks to check
            actual result.
        '400':
          description: >-
            Bad request - possible reasons:

            1. Missing `enableImmediatePlaceOrder` permission (upgrade plan
            required)

            2. Rate limit exceeded (max 5 attempts/hour per contract)

            3. Invalid billing attempt status (e.g., already SUCCESS)

            4. Contract canceled or payment method missing
        '401':
          description: Authentication required - invalid or missing API key
        '404':
          description: >-
            Billing attempt not found with provided ID or doesn't belong to
            authenticated shop
        '500':
          description: >-
            Internal server error - Shopify API unavailable or background job
            queue failure. Retry after 5 minutes.
  /api/external/v2/subscription-billing-attempts-update-order-note/{id}:
    put:
      tags:
        - Billing & Orders
        - Subscription Billing
      summary: Update order note for billing attempt
      description: >-
        Updates the order note/instructions for a specific upcoming billing
        attempt. These notes are stored with the billing attempt and will appear
        on the Shopify order when it's created. Order notes are visible to
        merchants in Shopify admin and can be printed on packing slips.


        **How It Works:**

        1. Accepts a billing attempt ID and new order note text

        2. Updates the billing attempt record immediately

        3. Note will be included when the order is created during billing

        4. Previous order note (if any) is completely replaced

        5. Empty string will clear the existing order note


        **Important Timing Considerations:**

        - Can only update billing attempts with status: `QUEUED` or `SCHEDULED`

        - Cannot update billing attempts that have already been processed
        (`SUCCESS` or `FAILED`)

        - Changes apply to the next billing cycle only (does not affect past
        orders)

        - For recurring notes across all future orders, use subscription
        contract order notes instead


        **Character Limits & Validation:**

        - **Maximum Length**: 5000 characters (Shopify's order note limit)

        - **Encoding**: Supports UTF-8 (emojis, international characters
        allowed)

        - **HTML**: Not rendered - plain text only, HTML tags will display as
        text

        - **Line Breaks**: Preserved using `\n` characters

        - **Special Characters**: Quotes, apostrophes automatically escaped


        **Common Use Cases:**

        - **Delivery Instructions**: "Please leave package at side door" or
        "Ring doorbell twice"

        - **Special Handling**: "Fragile items - handle with care" or
        "Refrigerate immediately"

        - **Gift Messages**: "Happy Birthday! Love, Sarah" (for gift
        subscriptions)

        - **Custom Requests**: "Include extra ice packs" or "No substitutions
        please"

        - **One-Time Changes**: "Skip broccoli this week, double the carrots
        instead"

        - **Fulfillment Notes**: "Use expedited shipping" or "Pack items
        separately"


        **Order Note vs Contract Note:**

        - **Billing Attempt Note** (this endpoint): Applies to ONE specific
        upcoming order only

        - **Contract Note** (`/subscription-contracts-update-order-note`):
        Applies to ALL future orders

        - If both exist, they are concatenated in the final Shopify order


        **Example Workflows:**

        ```

        Scenario 1: One-time delivery instruction

        1. Customer going on vacation next week

        2. Call this endpoint to add "Deliver to neighbor at #123" for next
        billing attempt

        3. Following orders resume normal delivery (no note)


        Scenario 2: Clearing unwanted notes

        1. Previous note says "Call before delivery"

        2. Customer requests removal

        3. Call this endpoint with orderNote="" (empty string)

        4. Note cleared from next order


        Scenario 3: Gift message for specific order

        1. Customer's subscription ships to recipient monthly

        2. Special occasion (birthday) on next delivery

        3. Add gift message to next billing attempt only

        4. Regular shipments continue without message

        ```


        **Integration Tips:**

        - Fetch upcoming billing attempts via `/subscription-billing-attempts`
        endpoint first

        - Check `status` field to ensure billing attempt can be modified

        - Display character counter in UI (5000 char limit)

        - Sanitize input to prevent injection attacks

        - Consider validating against profanity/spam filters


        **Error Handling:**

        - **404**: Billing attempt ID doesn't exist or belongs to different shop

        - **400**: Billing attempt already processed (status is SUCCESS/FAILED)

        - **400**: Order note exceeds 5000 character limit

        - **401**: Invalid or missing API key


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: updateOrderNoteV2_1
      parameters:
        - name: id
          in: path
          description: Billing attempt ID
          required: true
          schema:
            type: integer
            format: int64
          example: 123456
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: orderNote
          in: query
          description: Order note/instructions text
          required: true
          schema:
            type: string
          example: Please leave at front door
      responses:
        '200':
          description: Order note updated successfully. Returns true if update succeeded.
          content:
            '*/*':
              schema:
                type: boolean
        '400':
          description: >-
            Bad request - billing attempt already processed, note too long
            (>5000 chars), or invalid status for updates
          content:
            '*/*':
              schema:
                type: boolean
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                type: boolean
        '404':
          description: >-
            Billing attempt not found for the provided ID or doesn't belong to
            authenticated shop
          content:
            '*/*':
              schema:
                type: boolean
  /api/external/v2/product-swaps-by-variant-groups:
    post:
      tags:
        - Product Swap Rules
      summary: Get product swap options for subscription items
      description: >-
        Retrieves available product swap/substitution options for specified
        variants based on configured swap rules. Returns multiple levels of swap
        suggestions allowing members to exchange products in their
        subscriptions.


        **Key Features:**

        - **Variant-Based Swaps**: Get swap options for specific product
        variants

        - **Multi-Level Suggestions**: Returns up to 4 levels of swap
        alternatives

        - **Quantity Preservation**: Maintains quantities when suggesting swaps

        - **Recurring Order Rules**: Only returns swaps configured for every
        recurring order

        - **Group-Based Matching**: Uses variant groups to find compatible swaps

        - **Product Enrichment**: Includes product details (title, price,
        images)


        **How Swap Rules Work:**

        1. Merchant configures swap rules defining which products can substitute
        others

        2. Rules are organized by variant groups (e.g., coffee roasts, tea
        flavors)

        3. Each rule specifies "from" variants and "to" variants

        4. Rules can be limited to specific subscription frequencies or all
        orders

        5. Members can swap products within the allowed groups


        **Request Structure:**

        - **Variant Quantity List**: Array of variant IDs with quantities

        - Each entry contains variant ID and quantity

        - System finds swap options for all provided variants


        **Response Structure:**

        - Returns nested list of swap options (up to 5 levels)

        - Level 0: Original variants (as provided in request)

        - Levels 1-4: Progressive swap suggestions

        - Each level contains variant IDs, quantities, titles, prices, images

        - Variants appear with full Shopify product data


        **Use Cases:**

        - Display product swap options in customer portal

        - Allow members to switch between flavor/size variants

        - Build custom product selection interfaces

        - Enable seasonal product swaps (summer/winter varieties)

        - Offer alternative products when items are out of stock

        - Let members customize subscriptions within allowed product groups


        **Example Scenario:**

        Member has "Dark Roast Coffee (12oz)" in subscription. API returns:

        - Level 0: Dark Roast Coffee 12oz (original)

        - Level 1: Medium Roast Coffee 12oz, Light Roast Coffee 12oz

        - Level 2: Dark Roast Coffee 16oz, Decaf Dark Roast 12oz

        - Level 3: Espresso Blend 12oz, French Roast 12oz

        - Level 4: Additional variants based on swap rules


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getProductSwapsByVariantIdV2
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          description: >-
            API Key for authentication (Preferred method - use this instead of
            api_key parameter)
          required: false
          schema:
            type: string
      requestBody:
        description: List of variants with quantities to find swap options for
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VariantQuantityInfo'
            example:
              variantQuantityList:
                - variantId: 123456
                  quantity: 2
                - variantId: 789012
                  quantity: 1
        required: true
      responses:
        '200':
          description: >-
            Swap options successfully retrieved with up to 5 levels of
            suggestions
          content:
            application/json:
              schema:
                type: array
                description: >-
                  Nested list where each element is a list of variant options
                  for that swap level
        '400':
          description: Invalid variant information provided
          content:
            '*/*':
              schema:
                type: array
                items:
                  type: array
                  items:
                    $ref: '#/components/schemas/VariantQuantity'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                type: array
                items:
                  type: array
                  items:
                    $ref: '#/components/schemas/VariantQuantity'
        '404':
          description: No swap rules configured for shop
          content:
            '*/*':
              schema:
                type: array
                items:
                  type: array
                  items:
                    $ref: '#/components/schemas/VariantQuantity'
  /api/external/v2/delivery-profiles/v2/create-shipping-profile:
    post:
      tags:
        - Shipping & Delivery Profiles
      summary: Create shipping/delivery profile (V2 format)
      description: >-
        Creates a new Shopify delivery profile with custom shipping zones,
        rates, and methods. Delivery profiles control which shipping options are
        available to customers at checkout for subscription orders.


        **What is a Delivery Profile?**

        A delivery profile defines shipping configurations (zones, rates,
        methods) for specific products or locations. Subscription memberships
        can have dedicated delivery profiles with custom shipping pricing (free
        shipping for VIPs, regional rates, express delivery options, etc.).


        **Request Body Structure (CreateShippingProfileRequestV2):**

        ```json

        {
          "profileName": "VIP Membership Free Shipping",
          "locationInfos": [
            {
              "locationId": "gid://shopify/Location/12345",
              "countryInfos": [
                {
                  "countryCode": "US",
                  "provinceCodeInfoList": ["CA", "NY", "TX"],
                  "deliveryMethodInfo": [
                    {
                      "name": "Standard Shipping",
                      "amount": 0.00,
                      "currencyCode": "USD",
                      "minWeight": null,
                      "maxWeight": null,
                      "description": "Free for members"
                    },
                    {
                      "name": "Express Shipping",
                      "amount": 9.99,
                      "currencyCode": "USD",
                      "description": "2-day delivery"
                    }
                  ]
                }
              ]
            }
          ]
        }

        ```


        **Field Explanations:**


        **profileName** (string, required):

        - Unique name for the delivery profile

        - Visible in Shopify admin

        - Examples: "Premium Member Shipping", "International Free Shipping",
        "Express Delivery Profile"

        - Max length: 255 characters


        **locationInfos** (array, required):

        - Array of store locations this profile applies to

        - Get location IDs via Shopify Admin API or `/data/locations` endpoint

        - Can configure different shipping for each warehouse/store

        - **locationId** format: `gid://shopify/Location/{numeric_id}`


        **countryInfos** (array, required):

        - Shipping configuration per country

        - **countryCode**: ISO 3166-1 alpha-2 code ("US", "CA", "GB", etc.)

        - **provinceCodeInfoList**: Optional state/province filtering (e.g.,
        ["CA", "NY"] for US states)
          - Omit to include all provinces/states
          - Use ISO 3166-2 province codes (e.g., "CA" for California, "ON" for Ontario)

        **deliveryMethodInfo** (array, required):

        - Shipping methods available for this zone

        - **name**: Method display name ("Standard", "Express", "Overnight")

        - **amount**: Shipping cost (0.00 for free shipping)

        - **currencyCode**: Auto-set to shop currency (do not manually specify)

        - **minWeight** / **maxWeight**: Optional weight restrictions in grams

        - **description**: Optional customer-facing description


        **Common Use Cases & Examples:**


        **1. Free Shipping for VIP Members**

        ```json

        {
          "profileName": "VIP Free Shipping",
          "locationInfos": [{
            "locationId": "gid://shopify/Location/67890",
            "countryInfos": [{
              "countryCode": "US",
              "deliveryMethodInfo": [{
                "name": "Free Standard Shipping",
                "amount": 0.00,
                "description": "Included with VIP membership"
              }]
            }]
          }]
        }

        ```


        **2. Regional Pricing (Different Rates per State)**

        ```json

        {
          "profileName": "Regional Shipping",
          "locationInfos": [{
            "locationId": "gid://shopify/Location/12345",
            "countryInfos": [
              {
                "countryCode": "US",
                "provinceCodeInfoList": ["CA", "OR", "WA"],
                "deliveryMethodInfo": [{
                  "name": "West Coast Shipping",
                  "amount": 4.99
                }]
              },
              {
                "countryCode": "US",
                "provinceCodeInfoList": ["NY", "NJ", "CT"],
                "deliveryMethodInfo": [{
                  "name": "East Coast Shipping",
                  "amount": 5.99
                }]
              }
            ]
          }]
        }

        ```


        **3. Tiered Shipping (Standard + Express)**

        ```json

        {
          "profileName": "Multi-Speed Shipping",
          "locationInfos": [{
            "locationId": "gid://shopify/Location/12345",
            "countryInfos": [{
              "countryCode": "US",
              "deliveryMethodInfo": [
                {
                  "name": "Standard (5-7 days)",
                  "amount": 0.00,
                  "description": "Free standard shipping"
                },
                {
                  "name": "Express (2-3 days)",
                  "amount": 9.99,
                  "description": "Faster delivery"
                },
                {
                  "name": "Overnight",
                  "amount": 24.99,
                  "description": "Next business day"
                }
              ]
            }]
          }]
        }

        ```


        **Validation Rules:**

        - **profileName**: Required, non-empty, max 255 characters

        - **locationInfos**: Must contain at least 1 location

        - **countryCode**: Must be valid ISO 3166-1 alpha-2 code

        - **provinceCodeInfoList**: Optional, must be valid province codes for
        the country

        - **deliveryMethodInfo**: Must have at least 1 method per country

        - **amount**: Must be >= 0 (cannot be negative)

        - **locationId**: Must exist in Shopify and be active


        **Common Errors:**


        **400 - Invalid Country Code:**

        ```json

        {"error": "Invalid country code 'USA'. Use 'US' instead (ISO 3166-1
        alpha-2)"}

        ```

        Solution: Use 2-letter codes (US, CA, GB, AU, etc.)


        **400 - Invalid Location ID:**

        ```json

        {"error": "Location not found: gid://shopify/Location/99999"}

        ```

        Solution: Verify location exists via `/data/locations` endpoint


        **400 - Missing Delivery Methods:**

        ```json

        {"error": "Country US has no delivery methods configured"}

        ```

        Solution: Add at least one delivery method to each country


        **400 - Invalid Province Code:**

        ```json

        {"error": "Province code 'California' invalid for US. Use 'CA'"}

        ```

        Solution: Use 2-letter state codes (CA, NY, TX), not full names


        **500 - Shopify API Error:**

        Shopify's delivery profile API rejected the request. Common reasons:

        - Duplicate profile name

        - Missing required Shopify permissions

        - Shopify API rate limit exceeded

        - Invalid zone configuration


        **Response (DeliveryProfileDTO):**

        Returns created profile with:

        - `id`: Shopify delivery profile ID

        - `profileName`: Confirmed profile name

        - `active`: Whether profile is active (true by default)

        - `locationGroupId`: Shopify internal location group ID


        **How to Get Location IDs:**

        ```

        GET /api/data/locations

        Response:

        {
          "locations": {
            "nodes": [
              {
                "id": "gid://shopify/Location/12345",
                "name": "Main Warehouse"
              }
            ]
          }
        }

        ```


        **Best Practices:**

        1. **Test with One Country First**: Start with single country, add more
        after validation

        2. **Use Descriptive Names**: "VIP Free Shipping" better than "Profile
        1"

        3. **Verify Location IDs**: Always fetch current locations before
        creating profile

        4. **Set Reasonable Rates**: Research competitor shipping prices

        5. **Provide Descriptions**: Help customers understand shipping options

        6. **Weight Limits**: Use for heavy items requiring freight shipping


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: createShippingProfileV2External
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      requestBody:
        description: >-
          Delivery profile configuration with locations, zones, and shipping
          methods
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateShippingProfileRequestV2'
        required: true
      responses:
        '201':
          description: >-
            Delivery profile successfully created in Shopify. Returns
            DeliveryProfileDTO with profile ID and configuration.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeliveryProfileDTO'
        '400':
          description: >-
            Invalid request - validation failed. Common reasons: invalid
            country/province codes, missing delivery methods, negative amounts,
            invalid location ID format.
          content:
            application/json:
              example:
                title: Bad Request
                status: 400
                detail: >-
                  Invalid delivery profile configuration: Country code 'USA' is
                  invalid. Use ISO 3166-1 alpha-2 format (e.g., 'US')
                errorKey: validation_error
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/DeliveryProfileDTO'
        '500':
          description: >-
            Shopify API error during profile creation - possible causes:
            duplicate profile name, insufficient API permissions, rate limits,
            or Shopify service unavailable
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/DeliveryProfileDTO'
  /api/external/v2/delivery-profiles/create-shipping-profile:
    post:
      tags:
        - Shipping & Delivery Profiles
      summary: Create shipping/delivery profile (V1 format - Legacy)
      description: >-
        Creates a new Shopify delivery profile with shipping zones and rates
        using the legacy V1 format. For new integrations, prefer the V2 endpoint
        which supports more advanced configuration.


        **Key Features:**

        - **Single Location**: Configure shipping for primary store location

        - **Country-Based Zones**: Define shipping zones by country

        - **Fixed Rates**: Set flat shipping costs per zone

        - **Simple Configuration**: Straightforward setup for basic shipping
        needs


        **Configuration Structure:**

        - **Profile Name**: Unique identifier for the delivery profile

        - **Country Codes**: List of countries in the shipping zone

        - **Shipping Rate**: Fixed price for the zone

        - **Method Name**: Display name for the shipping option


        **Use Cases:**

        - Simple country-based flat rate shipping

        - Basic free shipping configuration

        - Legacy system migrations

        - Single-warehouse operations


        **Migration Note:** Consider using the V2 endpoint
        (`/api/external/v2/delivery-profiles/v2/create-shipping-profile`) for
        enhanced features like multi-location support, province targeting, and
        flexible rate types.


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: createShippingProfileV2
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      requestBody:
        description: >-
          Delivery profile configuration with country zones and shipping rates
          (V1 format)
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateShippingProfileRequestVM'
        required: true
      responses:
        '201':
          description: Delivery profile successfully created in Shopify
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeliveryProfileDTO'
        '400':
          description: Invalid request - validation failed
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/DeliveryProfileDTO'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/DeliveryProfileDTO'
        '500':
          description: Shopify API error during profile creation
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/DeliveryProfileDTO'
  /api/external/v2/subscription-groups:
    get:
      tags:
        - Membership Plans
      operationId: getAllSubscriptionGroupsExternalV2
      parameters:
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionGroupV2DTO'
  /api/external/v2/subscription-groups/{subscriptionGroupId}:
    get:
      tags:
        - Membership Plans
      operationId: getSubscriptionGroupV2
      parameters:
        - name: subscriptionGroupId
          in: path
          required: true
          schema:
            type: integer
            format: int64
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionGroupV2DTO'
  /api/external/v2/subscription-customers/{customerId}:
    get:
      tags:
        - Membership Contracts
      summary: Get subscription customer details
      description: >-
        Retrieves comprehensive customer information from Shopify for a specific
        customer ID. This endpoint fetches the customer record directly from
        Shopify's API, returning all personal details, addresses, payment
        methods, and metadata associated with the customer account.


        **What This Endpoint Returns:**

        Provides a complete Shopify Customer object containing all
        customer-related data for building customer portals, validating
        identities, displaying profiles, or integrating with external
        CRM/analytics systems.


        **Response Data Structure:**

        ```json

        {
          "id": "gid://shopify/Customer/6789012345",
          "email": "customer@example.com",
          "firstName": "Jane",
          "lastName": "Smith",
          "phone": "+1-555-123-4567",
          "displayName": "Jane Smith",
          "defaultAddress": {
            "address1": "123 Main St",
            "city": "San Francisco",
            "province": "CA",
            "zip": "94102",
            "country": "United States"
          },
          "addresses": [...],
          "tags": ["VIP", "Subscriber"],
          "note": "Prefers morning deliveries",
          "state": "ENABLED",
          "createdAt": "2023-01-15T10:30:00Z"
        }

        ```


        **Customer Data Fields Returned:**


        **Personal Information:**

        - `id` - Shopify global customer ID (format:
        `gid://shopify/Customer/{numeric_id}`)

        - `firstName` - Customer's first name

        - `lastName` - Customer's last name

        - `displayName` - Full name for display purposes

        - `email` - Primary email address (unique identifier)

        - `phone` - Contact phone number (optional, may be null)


        **Address Information:**

        - `defaultAddress` - Primary shipping/billing address object
          - `address1`, `address2` - Street address lines
          - `city`, `province`, `zip`, `country` - Location details
          - `provinceCode`, `countryCodeV2` - Standardized codes
          - `company` - Company name (if B2B customer)
        - `addresses` - Array of all saved addresses (shipping + billing)


        **Account Status:**

        - `state` - Account status: `ENABLED`, `DISABLED`, `INVITED`, `DECLINED`

        - `verifiedEmail` - Whether email has been verified (boolean)

        - `taxExempt` - Tax exemption status (boolean)

        - `acceptsMarketing` - Email marketing opt-in status


        **Metadata & Custom Fields:**

        - `tags` - Array of customer tags for segmentation

        - `note` - Merchant notes about the customer

        - `metafields` - Custom data fields (if queried)

        - `numberOfOrders` - Total lifetime order count


        **Timestamps:**

        - `createdAt` - When customer account was created

        - `updatedAt` - Last modification timestamp


        **Common Use Cases & Integration Scenarios:**


        **1. Customer Portal - Profile Display**

        ```

        Use Case: Show customer their account information

        1. Get customerId from session/JWT token

        2. Call GET /subscription-customers/{customerId}

        3. Display: Name, Email, Default Address

        4. Show "Edit Profile" button linking to address update endpoint

        ```


        **2. Pre-fill Shipping Address Form**

        ```

        Use Case: Auto-populate address form when updating shipping

        1. Fetch customer data via this endpoint

        2. Extract defaultAddress object

        3. Pre-fill form fields with existing address

        4. Allow customer to edit and submit changes

        ```


        **3. Identity Verification Before Critical Actions**

        ```

        Use Case: Verify customer email before canceling subscription

        1. User clicks "Cancel Subscription"

        2. Fetch customer data

        3. Compare session email with customer.email

        4. If mismatch: Reject (security violation)

        5. If match: Proceed with cancellation

        ```


        **4. CRM Integration / Analytics**

        ```

        Use Case: Sync customer data to external CRM (Salesforce, HubSpot)

        1. Webhook triggers on customer update

        2. Call this endpoint to get fresh customer data

        3. Map fields to CRM schema

        4. Push to CRM via their API

        ```


        **5. Customer Segmentation**

        ```

        Use Case: Filter customers by tags for targeted campaigns

        1. Fetch customer details

        2. Check tags array for "VIP" or "Churned"

        3. Apply special pricing or retention offers

        4. Customize email communications

        ```


        **Customer ID Format & Validation:**

        - **Input**: Numeric Shopify customer ID (e.g., `6789012345`)

        - **Not Accepted**: GraphQL global ID format (will cause 400 error)

        - **Extraction from GraphQL ID**: If you have
        `gid://shopify/Customer/6789012345`, extract `6789012345`

        - **Example Valid IDs**: `123`, `456789`, `9876543210`


        **Privacy & Security Considerations:**


        **PII Protection:**

        - This endpoint returns **personally identifiable information (PII)**

        - Ensure compliance with GDPR, CCPA, and privacy regulations

        - Only expose customer data to authenticated, authorized users

        - Do not log full customer records (contains emails, addresses, phone
        numbers)


        **Access Control:**

        - Customer can only access their own data (enforced by authentication)

        - Merchants can access all customers via API key

        - Never expose API keys in frontend code

        - Use server-to-server calls for merchant access


        **Data Minimization:**

        - Only fetch customer data when necessary

        - Cache responsibly with short TTL (5-10 minutes max)

        - Clear cache on customer updates


        **Error Handling & Edge Cases:**


        **404 - Customer Not Found:**

        ```

        Reasons:

        - Customer ID doesn't exist in Shopify

        - Customer was deleted from Shopify admin

        - Wrong shop (customer belongs to different store)

        - Typo in customer ID


        Solution:

        - Verify customer ID is correct

        - Check if customer exists in Shopify admin

        - Ensure shop domain matches customer's store

        ```


        **400 - Invalid Customer ID Format:**

        ```

        Reasons:

        - Non-numeric customer ID provided

        - Negative number or zero

        - GraphQL format instead of numeric ID


        Solution:

        - Ensure customer ID is positive integer

        - Extract numeric portion from GraphQL ID if needed

        ```


        **401 - Authentication Failed:**

        ```

        Reasons:

        - Missing API key or customer portal token

        - Expired authentication token

        - Invalid API key for the shop


        Solution:

        - Verify X-API-Key header is set

        - Regenerate API key if compromised

        - Check token expiration

        ```


        **Null/Empty Fields:**

        Some fields may be null/empty if customer hasn't provided data:

        - `phone` - Not all customers provide phone numbers

        - `addresses` - New customers may have empty address list

        - `defaultAddress` - Could be null if no addresses saved

        - `note` - Empty unless merchant added notes

        - `tags` - Empty array if no tags assigned


        Always handle null checks in your code.


        **Performance & Caching Recommendations:**

        - **Response Time**: Typically 100-300ms (Shopify GraphQL query)

        - **Rate Limits**: Subject to Shopify API rate limits (40
        requests/second)

        - **Caching**: Safe to cache for 5-10 minutes (customer data changes
        infrequently)

        - **Optimization**: Fetch once per session, store in memory/local state


        **Related Endpoints:**

        - `/subscription-customers-detail/valid/{customerId}` - Gets customer +
        subscription details

        - `/subscription-contract-details` - Lists all subscriptions for
        customer

        - `/customer-payments/token/{customerId}` - Get customer payment tokens

        - `/customer-portal-token` - Generate authentication token for customer


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter. Customer portal tokens also supported for
        self-service access.
      operationId: getSubscriptionCustomerV2
      parameters:
        - name: customerId
          in: path
          description: Shopify customer ID
          required: true
          schema:
            type: integer
            format: int64
          example: 6789012345
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      responses:
        '200':
          description: >-
            Customer details retrieved successfully. Returns full Shopify
            Customer object with all fields populated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '400':
          description: >-
            Bad request - invalid customer ID format (must be numeric positive
            integer, not GraphQL global ID)
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/Customer'
        '401':
          description: >-
            Authentication required - invalid or missing API key / customer
            portal token
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/Customer'
        '404':
          description: >-
            Customer not found - customer ID doesn't exist, was deleted, or
            belongs to different shop
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/Customer'
        '500':
          description: >-
            Internal server error - Shopify API unavailable or query timeout.
            Retry after brief delay.
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/Customer'
  /api/external/v2/subscription-customers/valid/{customerId}:
    get:
      tags:
        - Membership Contracts
      summary: Get valid subscription contract IDs for customer
      description: >-
        Retrieves a list of all valid (active, paused, or pending) subscription
        contract IDs associated with a specific customer. This endpoint is
        useful for quickly checking which subscriptions a customer has without
        retrieving full contract details.


        **Key Features:**

        - **Quick Lookup**: Returns only contract IDs, not full contract details

        - **Active Subscriptions Only**: Excludes cancelled or expired contracts

        - **Set Response**: Returns unique contract IDs (no duplicates)

        - **Fast Performance**: Lightweight query for list views


        **Included Subscription Statuses:**

        - **ACTIVE**: Currently active recurring subscriptions

        - **PAUSED**: Temporarily paused but valid subscriptions

        - **PENDING**: Scheduled to start in the future


        **Excluded Subscription Statuses:**

        - **CANCELLED**: Customer-cancelled subscriptions

        - **EXPIRED**: Reached max cycles or end date

        - **FAILED**: Failed billing with no recovery


        **Common Use Cases:**

        - **Subscription Count**: Quickly determine how many active
        subscriptions a customer has

        - **Access Control**: Verify customer has valid subscriptions before
        showing portal

        - **List Navigation**: Build dropdown or list of customer's
        subscriptions

        - **Bulk Operations**: Get all contract IDs for batch processing

        - **Validation**: Check if customer has any active memberships

        - **Dashboard Display**: Show subscription count without full data


        **Example Response:**

        ```json

        [12345, 12346, 12389]

        ```


        **Parameters:**

        - **customerId** (required, path): The Shopify customer ID


        **Response:**

        Returns a Set of Long values representing valid subscription contract
        IDs


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getValidSubscriptionCustomerV2
      parameters:
        - name: customerId
          in: path
          description: Shopify customer ID
          required: true
          schema:
            type: integer
            format: int64
          example: 6789012345
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      responses:
        '200':
          description: >-
            Valid subscription contract IDs retrieved successfully (may be empty
            set if customer has no active subscriptions)
          content:
            application/json:
              schema:
                type: string
        '400':
          description: Invalid customer ID format
          content:
            '*/*':
              schema:
                uniqueItems: true
                type: array
                items:
                  type: integer
                  format: int64
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                uniqueItems: true
                type: array
                items:
                  type: integer
                  format: int64
        '404':
          description: Customer not found
          content:
            '*/*':
              schema:
                uniqueItems: true
                type: array
                items:
                  type: integer
                  format: int64
  /api/external/v2/subscription-customers-detail/valid/{customerId}:
    get:
      tags:
        - Subscription Contract Management
        - Membership Contracts
      summary: Get detailed customer subscription information
      description: >-
        Retrieves comprehensive details for all subscription contracts
        associated with a specific customer. This endpoint returns complete
        subscription contract data including products, pricing, billing
        schedule, and status.


        **Key Information Returned:**

        - **Contract Details**: Contract ID, status (active, paused, cancelled),
        creation date

        - **Products**: Line items with product names, variants, quantities, and
        prices

        - **Billing Information**: Next billing date, billing frequency, payment
        method

        - **Delivery Details**: Shipping address, delivery method, delivery
        frequency

        - **Pricing**: Subtotal, discounts applied, total amount per cycle

        - **Membership Plan**: Associated subscription plan name and details

        - **Order History**: Past billing attempts and fulfillment records


        **Subscription Contract Details Include:**

        - **Contract ID**: Unique identifier for the subscription

        - **Customer ID**: Shopify customer ID associated with the contract

        - **Status**: ACTIVE, PAUSED, CANCELLED, EXPIRED

        - **Billing Cycle**: Number of completed billing cycles

        - **Next Billing Date**: When the next payment will be charged

        - **Delivery Date**: When the next order will be shipped

        - **Products**: All line items in the subscription with pricing

        - **Discount Codes**: Applied discount codes and their values

        - **Custom Attributes**: Any custom metadata or tags


        **Common Use Cases:**

        - Display full subscription list in customer account dashboard

        - Retrieve all contract details for customer support inquiries

        - Build custom customer portal with subscription management

        - Sync subscription data to external CRM or analytics systems

        - Generate customer subscription reports and analytics

        - Validate customer's active subscriptions before offering upgrades

        - Show subscription history and upcoming deliveries


        **Response Format:**

        Returns a List of SubscriptionContractDetailsDTO objects, one per
        active/paused contract. If customer has no subscriptions, returns an
        empty list.


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getValidSubscriptionCustomerDetailsV2
      parameters:
        - name: customerId
          in: path
          description: Shopify customer ID
          required: true
          schema:
            type: integer
            format: int64
          example: 6789012345
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      responses:
        '200':
          description: >-
            Customer subscription details successfully retrieved (may be empty
            list if no subscriptions)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContractDetailsDTO'
        '400':
          description: Invalid customer ID format
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractDetailsDTO'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractDetailsDTO'
        '404':
          description: Customer not found
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractDetailsDTO'
  /api/external/v2/subscription-custom-csses/{id}:
    get:
      tags:
        - Custom CSS Styling
      summary: Get custom CSS styling configuration
      description: >-
        Retrieves custom CSS styles configured for subscription widgets and
        customer portal. These styles allow merchants to customize the visual
        appearance of subscription elements to match their brand.


        **Use Cases:**

        - Apply custom styling to subscription widgets on storefront

        - Customize customer portal appearance

        - Match brand colors and fonts

        - Override default widget styles


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getSubscriptionCustomCssV2
      parameters:
        - name: id
          in: path
          description: Shop identifier
          required: true
          schema:
            type: integer
            format: int64
          example: mystore.myshopify.com
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          description: >-
            API Key for authentication (Preferred method - use this instead of
            api_key parameter)
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Custom CSS configuration successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionCustomCssDTO'
        '401':
          description: Authentication required
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionCustomCssDTO'
        '404':
          description: Custom CSS configuration not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionCustomCssDTO'
  /api/external/v2/subscription-contracts/contract-external/{contractId}:
    get:
      tags:
        - Membership Contracts
      summary: Get raw subscription contract details from Shopify
      description: >-
        Retrieves the complete subscription contract data directly from
        Shopify's GraphQL API. This returns the full, unmodified Shopify
        contract object with all nested data.


        **Key Features:**

        - **Raw Shopify Data**: Direct response from Shopify API, not
        transformed

        - **Complete Contract**: All contract fields, line items, billing
        details

        - **Real-Time Data**: Fetches current state from Shopify (not cached)

        - **Nested Objects**: Includes customer, addresses, discounts, line
        items


        **Returned Contract Data:**

        - **Contract ID & Status**: Shopify global ID, status
        (ACTIVE/PAUSED/CANCELLED/EXPIRED)

        - **Customer Info**: Customer object with name, email, addresses

        - **Line Items**: Products/variants in subscription with quantities,
        prices

        - **Billing Details**: Next billing date, billing policy (frequency,
        interval)

        - **Delivery Details**: Delivery policy, shipping address, method

        - **Pricing**: Line prices, discounts, currency code

        - **Dates**: Created at, updated at, next billing date

        - **Custom Attributes**: Any custom data attached to the contract

        - **Discounts**: Applied discount codes with amounts


        **Common Use Cases:**

        - **Full Contract Display**: Show all contract details in admin/portal

        - **Debugging**: Inspect raw Shopify contract structure

        - **Data Export**: Get complete contract for reporting/analytics

        - **Integration Development**: Understand Shopify's contract schema

        - **Audit Trail**: Capture complete contract state at a point in time


        **Differences from other endpoints:**

        - This returns Shopify's raw contract object

        - `/api/external/v2/subscription-contract-details` returns transformed
        DTO

        - This includes more nested Shopify-specific fields


        **Parameters:**

        - **contractId** (required, path): The subscription contract ID
        (numeric)


        **Response:**

        Returns complete Shopify SubscriptionContract GraphQL object


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getSubscriptionContractRawExternalV2
      parameters:
        - name: contractId
          in: path
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 12345
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Subscription contract retrieved successfully from Shopify
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '400':
          description: Invalid contract ID format
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '404':
          description: Subscription contract not found in Shopify
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
        '500':
          description: Shopify API error
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionContract'
  /api/external/v2/subscription-contracts-email-magic-link:
    get:
      tags:
        - Subscription Contract Management
        - Membership Contracts
      summary: Send customer portal magic link via email
      description: >-
        Automatically generates and emails a secure magic link to the customer
        for accessing their subscription management portal. This is a
        convenience endpoint that combines token generation and email delivery
        in a single API call.


        **Key Features:**

        - **Automated Delivery**: Generates magic link and sends email in one
        operation

        - **Customer Lookup**: Finds customer by email address automatically

        - **Branded Emails**: Uses shop's configured email templates and
        branding

        - **Subscription Validation**: Only sends if customer has active
        subscriptions

        - **Time-Limited Links**: Email contains token that expires after
        configured duration


        **Email Contents:**

        The sent email typically includes:

        - **Magic Link Button**: One-click access to customer portal

        - **Link URL**: Full URL with embedded authentication token

        - **Expiration Notice**: When the link will expire (e.g., "Valid for 24
        hours")

        - **Shop Branding**: Store logo, colors, and custom messaging

        - **Help Text**: Instructions on how to use the portal


        **Workflow:**

        1. API receives customer email address

        2. System looks up customer in Shopify by email

        3. Validates customer has active subscription contracts

        4. Generates secure JWT authentication token

        5. Constructs magic link URL with token

        6. Sends branded email with magic link to customer

        7. Returns success confirmation to API caller


        **Email Template Customization:**

        Email appearance and content can be customized via:

        - Shop's email notification settings in admin

        - Custom email templates for magic links

        - Localization settings for customer's language

        - Custom branding (logo, colors, footer)


        **Common Use Cases:**

        - Customer support: send portal access link to customers over phone/chat

        - Automated workflows: trigger magic link emails based on events

        - Forgot password alternative: passwordless portal access

        - Post-purchase flows: send portal access after first order

        - Reactivation campaigns: re-engage paused/cancelled customers

        - Customer onboarding: welcome emails with portal access

        - Subscription reminders: include portal link in reminder emails


        **Integration Example:**

        ```

        GET /api/external/v2/subscription-contracts-email-magic-link?
          email=customer@example.com&
          api_key=your_api_key
        ```

        This sends a magic link email to customer@example.com for portal access.


        **Error Handling:**

        - If customer not found, returns 400 Bad Request

        - If customer has no active subscriptions, returns 400

        - If email service fails, returns 500 Internal Server Error

        - Invalid email format returns 400 Bad Request


        **Email Delivery Notes:**

        - Emails are sent asynchronously (may take 1-5 minutes to deliver)

        - Check spam folders if customer doesn't receive email

        - Respect customer's email preferences and unsubscribe status

        - Rate limits may apply to prevent abuse


        **Security Considerations:**

        - Only send to verified customer email addresses

        - Email contains passwordless authentication link

        - Links expire after configured duration (default: 24-72 hours)

        - Sending to wrong email grants that person subscription access

        - Consider email verification before using this endpoint


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: emailMagicLinkV2
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: email
          in: query
          description: Customer email address to send magic link to
          required: true
          schema:
            type: string
          example: customer@example.com
      responses:
        '200':
          description: Magic link email sent successfully to customer
          content:
            text/plain:
              schema:
                type: string
        '400':
          description: >-
            Invalid request - customer email not found or no active
            subscriptions
          content:
            '*/*':
              schema:
                type: string
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                type: string
        '500':
          description: Error sending email
          content:
            '*/*':
              schema:
                type: string
  /api/external/v2/subscription-contract-one-offs-by-contractId:
    get:
      tags:
        - One-Time Add-Ons
      summary: Get one-time add-ons for a membership contract
      description: >-
        Retrieves all one-time product additions scheduled for upcoming orders
        of a specific membership contract. One-offs are products added to a
        single billing cycle without affecting the recurring subscription items.


        **Key Information Returned:**

        - **One-Off Items**: List of products added to upcoming orders

        - **Product Details**: Variant ID, handle, title, price, image

        - **Billing Association**: Which billing attempt the item is added to

        - **Quantity**: Number of units for the one-time add-on

        - **Status**: Active, pending, or fulfilled one-offs

        - **Created Date**: When the one-off was added


        **One-Off Item Data:**

        - **Contract ID**: Parent subscription contract

        - **Billing Attempt ID**: Specific order the item will be added to

        - **Variant Info**: Product variant being added

        - **Pricing**: One-time price for the add-on

        - **Fulfillment Status**: Whether item has been shipped


        **Use Cases:**

        - Display scheduled one-time add-ons in customer portal

        - Show customers which extra items are in next order

        - Sync one-off data with external order management systems

        - Generate custom order previews for customers

        - Build upsell dashboards showing add-on purchases

        - Track one-time product revenue per contract


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getOneOffsForSubscriptionContractV2
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 123456
      responses:
        '200':
          description: One-off items successfully retrieved
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractOneOffDTO'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractOneOffDTO'
        '403':
          description: Access forbidden - contract does not belong to authenticated shop
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractOneOffDTO'
        '404':
          description: Membership contract not found
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractOneOffDTO'
  /api/external/v2/subscription-contract-details:
    get:
      tags:
        - Membership Contracts
      summary: Get membership/subscription contract list
      description: >-
        Retrieves a paginated list of membership/subscription contracts with
        advanced filtering capabilities. This endpoint provides comprehensive
        access to all subscription contracts in your store with flexible query
        options.


        **Key Information Returned:**

        - **Contract Details**: Contract ID, status, creation date, billing
        cycle

        - **Customer Information**: Customer name, email, Shopify customer ID

        - **Subscription Items**: Products, variants, quantities in subscription

        - **Billing Information**: Next billing date, billing frequency, pricing

        - **Delivery Details**: Shipping address, delivery method, next delivery
        date

        - **Plan Information**: Membership plan type, selling plan IDs

        - **Status Tracking**: Active, paused, cancelled, expired states


        **Filtering Capabilities:**

        - **Date Ranges**: Filter by creation date or next billing date

        - **Customer Search**: Search by customer name or email

        - **Status Filter**: Filter by contract status (active, paused,
        cancelled)

        - **Plan Type**: Filter by membership plan type

        - **Billing Frequency**: Filter by billing interval (weekly, monthly,
        etc.)

        - **Product/Variant**: Find contracts containing specific products or
        variants

        - **Order Name**: Search by Shopify order name/number

        - **Selling Plan**: Filter by Shopify selling plan IDs

        - **Special Filters**: Contracts with deleted products or bounced emails


        **Pagination:**

        - Supports standard pagination parameters (page, size, sort)

        - Returns pagination headers for total count and navigation

        - Default page size configurable via request parameters


        **Use Cases:**

        - Export subscription data to external CRM or analytics systems

        - Build custom subscription dashboards and reports

        - Sync membership data with external platforms

        - Identify subscriptions needing attention (bounced emails, deleted
        products)

        - Generate subscription activity reports by date range

        - Find all subscriptions for a specific product or variant

        - Monitor subscription health and churn metrics


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getAllSubscriptionContractDetailsExternal
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: fromCreatedDate
          in: query
          description: Filter contracts created on or after this date
          required: false
          schema:
            type: string
            format: date-time
          example: '2024-01-01T00:00:00Z'
        - name: toCreatedDate
          in: query
          description: Filter contracts created on or before this date
          required: false
          schema:
            type: string
            format: date-time
          example: '2024-12-31T23:59:59Z'
        - name: fromNextDate
          in: query
          description: Filter contracts with next billing date on or after this date
          required: false
          schema:
            type: string
            format: date-time
          example: '2024-01-01T00:00:00Z'
        - name: toNextDate
          in: query
          description: Filter contracts with next billing date on or before this date
          required: false
          schema:
            type: string
            format: date-time
          example: '2024-12-31T23:59:59Z'
        - name: subscriptionContractId
          in: query
          description: Filter by specific subscription/membership contract ID
          required: false
          schema:
            type: string
          example: gid://shopify/SubscriptionContract/12345
        - name: customerName
          in: query
          description: Filter by customer name or email (partial match)
          required: false
          schema:
            type: string
          example: john@example.com
        - name: orderName
          in: query
          description: Filter by Shopify order name
          required: false
          schema:
            type: string
          example: '#1001'
        - name: status
          in: query
          description: Filter by subscription status
          required: false
          schema:
            type: string
            enum:
              - ACTIVE
              - PAUSED
              - CANCELLED
              - FAILED
              - EXPIRED
          example: ACTIVE
        - name: billingPolicyIntervalCount
          in: query
          description: Filter by billing frequency count (e.g., 1 for every 1 month)
          required: false
          schema:
            type: integer
            format: int32
          example: 1
        - name: billingPolicyInterval
          in: query
          description: Filter by billing frequency interval
          required: false
          schema:
            type: string
            enum:
              - DAY
              - WEEK
              - MONTH
              - YEAR
          example: MONTH
        - name: planType
          in: query
          description: Filter by plan type (PAY_AS_YOU_GO or PREPAID)
          required: false
          schema:
            type: string
            enum:
              - PAY_AS_YOU_GO
              - PREPAID
          example: PAY_AS_YOU_GO
        - name: recordType
          in: query
          description: Filter by record type (CONTRACT or SELLING_PLAN_GROUP)
          required: false
          schema:
            type: string
          example: CONTRACT
        - name: productId
          in: query
          description: Filter by Shopify product ID
          required: false
          schema:
            type: integer
            format: int64
          example: 123456789
        - name: variantId
          in: query
          description: Filter by Shopify product variant ID
          required: false
          schema:
            type: integer
            format: int64
          example: 987654321
        - name: sellingPlanIds
          in: query
          description: Filter by selling plan IDs (comma-separated for multiple)
          required: false
          schema:
            type: string
          example: 123,456,789
        - name: havingProductsDeletedFromStore
          in: query
          description: Include only contracts with products deleted from Shopify store
          required: false
          schema:
            type: boolean
            default: false
          example: false
        - name: emailBouncedOrFailed
          in: query
          description: Include only contracts where email notifications bounced or failed
          required: false
          schema:
            type: boolean
            default: false
          example: false
        - name: pageable
          in: query
          description: Pagination parameters (page number and size)
          required: true
          schema:
            $ref: '#/components/schemas/Pageable'
          example:
            page: 0
            size: 10
            sort:
              - id,desc
      responses:
        '200':
          description: >-
            Subscription contracts successfully retrieved with pagination
            headers
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionContractDetailsDTO'
        '400':
          description: Invalid filter parameters or date format
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractDetailsDTO'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionContractDetailsDTO'
  /api/external/v2/subscription-contract-details/{contractId}/pending-downgrade:
    get:
      tags:
        - Membership Contracts
      summary: Get pending downgrade for a subscription contract
      description: >-
        Retrieves the pending/scheduled downgrade details for a specific
        subscription contract. This endpoint returns information about a
        downgrade that has been scheduled but not yet executed.


        **Response Information:**

        - **contractId**: The subscription contract ID

        - **waitTillTimestamp**: When the downgrade will be executed

        - **oldVariantId**: The current product variant ID

        - **newVariantId**: The target product variant ID after downgrade

        - **oldPrice**: Current subscription price

        - **newPrice**: New price after downgrade

        - **sellingPlanId**: The selling plan ID for the new subscription

        - **sellingPlanName**: Name of the selling plan


        **Use Cases:**

        - Check if a customer has a pending downgrade scheduled

        - Display pending downgrade information in custom dashboards

        - Verify downgrade details before allowing further modifications


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getPendingDowngradeV2
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: contractId
          in: path
          description: The subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 12345
      responses:
        '200':
          description: Pending downgrade found and returned successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScheduledDowngradeRequest'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/ScheduledDowngradeRequest'
        '404':
          description: No pending downgrade found for this contract
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/ScheduledDowngradeRequest'
    delete:
      tags:
        - Membership Contracts
      summary: Cancel pending downgrade for a subscription contract
      description: >-
        Cancels a scheduled/pending downgrade for a specific subscription
        contract. This endpoint removes the pending downgrade so that the
        subscription will continue with its current plan.


        **Important Notes:**

        - The downgrade must be pending (not yet executed) to be cancelled

        - Once cancelled, the subscription will remain on its current plan

        - An activity log entry is created when a downgrade is cancelled


        **Use Cases:**

        - Allow customers to change their mind about a scheduled downgrade

        - Cancel downgrades when customers upgrade or renew

        - Administrative cancellation of pending plan changes


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: cancelPendingDowngradeV2
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: contractId
          in: path
          description: The subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 12345
      responses:
        '204':
          description: Pending downgrade cancelled successfully
        '401':
          description: Authentication required - invalid or missing API key
        '404':
          description: No pending downgrade found for this contract
  /api/external/v2/subscription-contract-details/subscription-fulfillments/{contractId}:
    get:
      tags:
        - Membership Contracts
      summary: Get subscription order fulfillment details
      description: >-
        Retrieves fulfillment information for the most recent order generated by
        a subscription contract. Shows shipping status, tracking numbers, and
        delivery progress.


        **Key Features:**

        - **Latest Order**: Returns fulfillment data for the most recent
        subscription order

        - **Tracking Info**: Includes tracking numbers, URLs, and shipping
        carriers

        - **Fulfillment Status**: Shows whether items are unfulfilled,
        fulfilled, or partially fulfilled

        - **Multi-Fulfillment**: Handles orders split across multiple shipments


        **Returned Fulfillment Data:**

        - **Order Info**: Order name/number, creation date, financial status

        - **Fulfillment Status**: FULFILLED, PARTIAL, UNFULFILLED, etc.

        - **Fulfillments List**: Array of all fulfillments for the order

        - **Tracking Numbers**: Tracking codes for each fulfillment

        - **Tracking URLs**: Direct links to carrier tracking pages

        - **Shipping Carrier**: Carrier name (USPS, FedEx, UPS, etc.)

        - **Fulfillment Date**: When each shipment was fulfilled

        - **Line Items**: Which products/variants are in each shipment

        - **Delivery Address**: Where the order is being shipped


        **Common Use Cases:**

        - **Order Tracking**: Show customers where their subscription delivery
        is

        - **Customer Portal**: Display "Track Your Order" links

        - **Shipping Updates**: Check fulfillment status for recent orders

        - **Support**: Help customers track delayed or missing shipments

        - **Notifications**: Trigger custom shipping notifications

        - **Analytics**: Track fulfillment performance metrics


        **Response Structure:**

        Returns an Order object containing:

        - Basic order information

        - Array of fulfillments with tracking details

        - Line items per fulfillment

        - Shipping and delivery information


        **Note:** This returns data for the MOST RECENT order only. For
        historical fulfillment data, use order history endpoints.


        **Parameters:**

        - **contractId** (required, path): The subscription contract ID


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getSubscriptionFulfillmentsExternalV2
      parameters:
        - name: contractId
          in: path
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 12345
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Fulfillment details retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Order'
        '400':
          description: Invalid contract ID format
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/Order'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/Order'
        '404':
          description: Subscription contract not found or no orders exist yet
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/Order'
        '500':
          description: Error retrieving fulfillment data from Shopify
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/Order'
  /api/external/v2/subscription-contract-details/billing-interval:
    get:
      tags:
        - Subscription Contract Management
        - Membership Contracts
      summary: Get billing interval options for selling plans
      description: >-
        Retrieves available billing frequency/interval options for specified
        Shopify selling plans (subscription plans). This endpoint returns all
        configured billing frequencies that customers can choose from for their
        subscriptions.


        **Key Information Returned:**

        - **Frequency Options**: List of available billing intervals (e.g.,
        weekly, monthly, quarterly)

        - **Interval Units**: Time unit for each option (DAYS, WEEKS, MONTHS,
        YEARS)

        - **Interval Count**: Number of units between billings (e.g., 2 = every
        2 weeks)

        - **Display Names**: Customer-friendly names for each frequency option

        - **Plan IDs**: Associated selling plan IDs for each frequency


        **Billing Frequency Structure:**

        Each FrequencyInfoDTO contains:

        - **id**: Selling plan ID (Shopify subscription plan identifier)

        - **name**: Display name (e.g., "Deliver every 2 weeks", "Monthly
        subscription")

        - **intervalUnit**: Time unit (DAY, WEEK, MONTH, YEAR)

        - **intervalCount**: Number of units between deliveries

        - **billingPolicy**: How billing is configured (EXACT_DAY, ANNIVERSARY)

        - **deliveryPolicy**: How delivery is scheduled


        **Common Billing Intervals:**

        - **Weekly**: intervalUnit=WEEK, intervalCount=1

        - **Bi-Weekly**: intervalUnit=WEEK, intervalCount=2

        - **Monthly**: intervalUnit=MONTH, intervalCount=1

        - **Every 2 Months**: intervalUnit=MONTH, intervalCount=2

        - **Quarterly**: intervalUnit=MONTH, intervalCount=3

        - **Semi-Annual**: intervalUnit=MONTH, intervalCount=6

        - **Annual**: intervalUnit=YEAR, intervalCount=1


        **Request Parameters:**

        - **sellingPlanIds**: Comma-separated list of Shopify selling plan IDs
        (required)
          - Example: "123456,123457,123458"
          - Returns frequency options for all specified plans

        **Common Use Cases:**

        - Display available billing frequencies in customer portal

        - Allow customers to change subscription delivery frequency

        - Build frequency selector UI components

        - Validate frequency options before updating subscription

        - Sync available billing options with external systems

        - Show frequency options during subscription checkout


        **Integration Example:**

        1. Get customer's current subscription selling plan ID

        2. Call this endpoint with that selling plan ID

        3. Display returned frequency options to customer

        4. Customer selects new frequency

        5. Update subscription with selected frequency


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getSubscriptionContractBillingInterval
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: sellingPlanIds
          in: query
          description: Comma-separated list of Shopify selling plan IDs
          required: true
          schema:
            type: string
          example: 123456,123457,123458
      responses:
        '200':
          description: Billing interval options successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FrequencyInfoDTO'
        '400':
          description: Invalid selling plan IDs format or missing required parameter
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/FrequencyInfoDTO'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/FrequencyInfoDTO'
  /api/external/v2/subscription-bundlings/external/get-bundle/{handle}:
    get:
      tags:
        - Product Bundles
      summary: Get bundle details by handle
      description: >-
        Retrieves detailed information about a subscription product bundle
        including bundled items, pricing, and subscription plan details.


        **Key Information Returned:**

        - **Bundle Configuration**: Name, handle, description, status

        - **Bundled Items**: Products included in the bundle with quantities

        - **Pricing**: Total price, individual item prices, discounts

        - **Subscription Details**: Associated membership plan, billing
        frequency

        - **Product Information**: Variant details, images, availability

        - **Display Settings**: How the bundle should be presented to customers


        **Bundle Components:**

        - Product handles and variant IDs

        - Quantity per product in the bundle

        - Bundle-level discounts or pricing rules

        - Subscription plan associations

        - Custom attributes and metadata


        **Use Cases:**

        - Display bundle details on product pages

        - Retrieve bundle configuration for cart integration

        - Show customers what's included in a bundle

        - Sync bundle data with external systems

        - Build custom bundle selection interfaces


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getValidSubscriptionCustomerV2_1
      parameters:
        - name: handle
          in: path
          description: Unique bundle identifier (handle/slug)
          required: true
          schema:
            type: string
          example: coffee-bundle-monthly
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Bundle details successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionBundlingResponse'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionBundlingResponse'
        '404':
          description: Bundle not found with the specified handle
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionBundlingResponse'
  /api/external/v2/subscription-bundle-settings/{id}:
    get:
      tags:
        - Bundle Settings
      summary: Get bundle settings
      description: >-
        Retrieves the subscription bundle configuration settings for the
        authenticated shop. Returns settings that control bundle behavior,
        pricing, and display options.


        **Key Features:**

        - Bundle display preferences

        - Pricing calculation rules

        - Bundle discount configurations

        - Widget behavior settings


        **Use Cases:**

        - Configure bundle widget behavior

        - Set bundle pricing rules

        - Customize bundle display options

        - Retrieve bundle configuration for frontend


        **Note:** The ID parameter is provided for compatibility but settings
        are retrieved by authenticated shop.


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getSubscriptionBundleSettingsV2
      parameters:
        - name: id
          in: path
          description: Settings ID (deprecated - retrieves by shop)
          required: true
          schema:
            type: integer
            format: int64
          example: 1
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Bundle settings retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionBundleSettingsDTO'
        '401':
          description: Authentication required
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionBundleSettingsDTO'
        '404':
          description: Bundle settings not found for shop
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/SubscriptionBundleSettingsDTO'
  /api/external/v2/subscription-billing-attempts/top-orders:
    get:
      tags:
        - Billing & Orders
        - Subscription Billing
      summary: Get upcoming orders
      description: >-
        Retrieves upcoming/scheduled billing attempts for shop, contract, or
        customer. Returns future orders that haven't been processed yet.


        **Query Options:**

        - No params: All upcoming orders for shop

        - contractId: Upcoming orders for specific contract

        - customerId: Upcoming orders for specific customer


        **Use Cases:**

        - Display next delivery dates in portal

        - Show upcoming charges

        - Allow order modifications before processing


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getTopOrdersV2
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: contractId
          in: query
          description: Filter by subscription contract ID
          required: false
          schema:
            type: integer
            format: int64
          example: 123456
        - name: customerId
          in: query
          description: Filter by customer ID
          required: false
          schema:
            type: integer
            format: int64
          example: 789012
      responses:
        '200':
          description: Upcoming orders retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionBillingAttemptDTO'
        '401':
          description: Authentication required
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionBillingAttemptDTO'
  /api/external/v2/subscription-billing-attempts/past-orders:
    get:
      tags:
        - Billing & Orders
        - Subscription Billing
      summary: Get past orders
      description: >-
        Retrieves historical billing attempts including successful, failed, and
        skipped orders. Returns completed billing attempts for reporting and
        history display.


        **Query Options:**

        - No params: All past orders for shop

        - contractId: Order history for specific contract

        - customerId: Order history for specific customer


        **Use Cases:**

        - Display order history in customer portal

        - Generate billing reports

        - Track payment success/failure rates

        - Customer service order lookup


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getPastOrdersV2
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: contractId
          in: query
          description: Filter by subscription contract ID
          required: false
          schema:
            type: integer
            format: int64
          example: 123456
        - name: customerId
          in: query
          description: Filter by customer ID
          required: false
          schema:
            type: integer
            format: int64
          example: 789012
      responses:
        '200':
          description: Past orders retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionBillingAttemptDTO'
        '401':
          description: Authentication required
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionBillingAttemptDTO'
  /api/external/v2/subscription-billing-attempts/past-orders/report:
    get:
      tags:
        - Billing & Orders
        - Billing Attempts
      summary: Get paginated past or upcoming orders report
      description: >-
        Retrieves a paginated list of subscription billing attempts filtered by
        status (SUCCESS, FAILURE, QUEUED, SKIPPED) with optional contract
        filtering.


        **Key Features:**

        - **Status Filtering**: Filter by SUCCESS (past successful orders),
        FAILURE (failed billing attempts), QUEUED (upcoming scheduled orders),
        or SKIPPED (intentionally skipped orders)

        - **Contract Filtering**: Optional filtering by specific subscription
        contract ID

        - **Pagination Support**: Returns paginated results with page headers

        - **Order History**: Access complete billing attempt history


        **Status Values:**

        - `SUCCESS`: Completed successful billing attempts (past orders)

        - `FAILURE`: Failed billing attempts that need attention

        - `QUEUED`: Upcoming scheduled billing attempts (future orders)

        - `SKIPPED`: Manually or automatically skipped billing attempts


        **Use Cases:**

        - Generate customer order history reports

        - Display upcoming scheduled deliveries

        - Track failed billing attempts for recovery

        - Export subscription order data for analysis

        - Monitor skipped orders and cancellations


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getPastOrdersReportV2
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: contractId
          in: query
          description: Filter by contract Id
          required: false
          schema:
            type: integer
            format: int64
        - name: status
          in: query
          description: Filter by status
          required: true
          schema:
            type: string
        - name: pageable
          in: query
          description: Pagination parameters (page number and size)
          required: true
          schema:
            $ref: '#/components/schemas/Pageable'
          example:
            page: 0
            size: 10
            sort:
              - id,desc
      responses:
        '200':
          description: Billing attempts successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionBillingAttemptDTO'
        '400':
          description: >-
            Invalid status parameter - must be SUCCESS, FAILURE, QUEUED, or
            SKIPPED
          content:
            application/json:
              example:
                title: Bad Request
                status: 400
                detail: Invalid status provided
                errorKey: validation_error
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionBillingAttemptDTO'
  /api/external/v2/manage-subscription-link/{customerId}:
    get:
      tags:
        - Subscription Contract Management
        - Membership Contracts
      summary: Generate customer portal magic link
      description: >-
        Generates a secure, time-limited magic link that allows customers to
        access and manage their subscriptions. This passwordless authentication
        link directs customers to the subscription management portal.


        **Magic Link Features:**

        - **Passwordless Access**: No login credentials required, link serves as
        authentication

        - **Time-Limited**: Link expires after configured duration (typically
        24-72 hours)

        - **Single Customer**: Link is bound to specific customer ID, cannot be
        reused for others

        - **Secure Token**: Uses cryptographically secure JWT tokens for
        authentication

        - **Customer Portal**: Directs to full-featured self-service
        subscription portal


        **Returned Information:**

        - **Magic Link URL**: Full URL to customer portal with embedded
        authentication token

        - **Token**: JWT token value (can be used separately if needed)

        - **Expiration Time**: When the magic link will expire (ISO 8601 format)

        - **Customer ID**: Shopify customer ID the link is generated for

        - **Shop Domain**: Store domain where subscriptions are hosted


        **Customer Portal Capabilities (via Magic Link):**

        - View all active and paused subscription contracts

        - Update shipping address for upcoming deliveries

        - Change payment method for future billing

        - Pause or resume subscription deliveries

        - Skip upcoming delivery orders

        - Modify delivery frequency (e.g., monthly to bi-monthly)

        - Add or remove products from subscription

        - Swap product variants (size, flavor, color)

        - Cancel subscription with reason feedback

        - View order history and upcoming deliveries

        - Apply discount codes to subscription


        **Common Use Cases:**

        - Send magic link via email for customer self-service

        - Include link in transactional emails (order confirmation, shipping
        notices)

        - Customer support: provide link to customers over phone/chat

        - Embed link in customer account page or dashboard

        - Automated email campaigns for subscription management reminders

        - Post-purchase flows to encourage subscription modifications

        - Win-back campaigns: send magic link to cancelled/paused customers


        **Security Notes:**

        - Links are single-use per session (new token generated each time)

        - Tokens include shop and customer validation to prevent tampering

        - Expired links automatically redirect to token request page

        - Links should be sent via secure channels (HTTPS, encrypted email)


        **Integration Best Practices:**

        - Always send magic links via email or SMS (don't display on public
        pages)

        - Set appropriate expiration time based on use case

        - Include clear call-to-action in emails ("Manage Your Subscription")

        - Handle expired tokens gracefully with re-send functionality

        - Track magic link generation for security audit logs


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getManageSubscriptionLink
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: customerId
          in: path
          description: Shopify customer ID
          required: true
          schema:
            type: integer
            format: int64
          example: 6789012345
      responses:
        '200':
          description: >-
            Magic link generated successfully, returns link URL and expiration
            time
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenDetails'
        '400':
          description: Invalid customer ID format
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/TokenDetails'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/TokenDetails'
        '404':
          description: Customer not found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/TokenDetails'
  /api/external/v2/customer-portal-token:
    get:
      tags:
        - Subscription Contract Management
        - Membership Contracts
      summary: Generate customer portal authentication token
      description: >-
        Generates an authentication token for customer portal access using
        either customer ID or email address. This token can be used to create
        magic links or authenticate API requests on behalf of a customer.


        **Key Features:**

        - **Flexible Lookup**: Find customer by Shopify customer ID OR email
        address

        - **JWT Token**: Returns cryptographically secure JSON Web Token

        - **Portal Access**: Token grants access to customer subscription
        management portal

        - **API Authentication**: Can be used in subsequent API calls for
        customer-specific operations

        - **Time-Limited**: Token expires after configured duration (default:
        24-72 hours)


        **Request Parameters:**

        Provide **either** customerId OR email (not both):

        - **customerId**: Shopify customer ID (numeric string, e.g.,
        "6789012345")

        - **email**: Customer's email address as registered in Shopify


        **Response Contains:**

        - **customerId**: Shopify customer ID associated with the token

        - **token**: JWT authentication token for portal access

        - **shop**: Store domain the customer belongs to

        - **expiresAt**: Token expiration timestamp (ISO 8601)


        **Common Use Cases:**

        - Generate token to construct customer portal magic links

        - Authenticate customer in headless commerce implementations

        - Validate customer identity before allowing subscription changes

        - Create custom portal integrations with embedded authentication

        - Server-side customer lookup when only email is available

        - Build custom subscription management UIs with API authentication

        - Integrate with external CRM systems requiring customer tokens


        **Token Usage:**

        Once generated, the token can be:

        1. Embedded in magic link URLs:
        `https://portal.example.com?token={token}`

        2. Used as Bearer token in Authorization headers for API calls

        3. Stored temporarily for customer session management

        4. Passed to frontend applications for customer-specific operations


        **Security Best Practices:**

        - Never expose tokens in client-side logs or browser storage

        - Transmit tokens only over HTTPS

        - Implement token rotation for long-lived sessions

        - Validate token expiration before use

        - Revoke tokens when customer logs out or changes credentials


        **Error Handling:**

        - If neither customerId nor email is provided, returns 400 Bad Request

        - If both customerId and email are provided, customerId takes precedence

        - If customer not found, returns 404 Not Found

        - Invalid email format returns 400 Bad Request


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getCustomerPortalToken
      parameters:
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: customerId
          in: query
          description: Shopify customer ID (provide either customerId OR email)
          required: false
          schema:
            type: string
          example: 6789012345
        - name: email
          in: query
          description: Customer email address (provide either customerId OR email)
          required: false
          schema:
            type: string
          example: customer@example.com
      responses:
        '200':
          description: >-
            Customer portal token generated successfully, returns customer ID
            and authentication token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerTokenInfo'
        '400':
          description: >-
            Invalid request - customer ID or email not provided, or customer not
            found
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/CustomerTokenInfo'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/CustomerTokenInfo'
        '404':
          description: Customer not found with provided ID or email
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/CustomerTokenInfo'
  /api/external/v2/customer-portal-settings/{id}:
    get:
      tags:
        - Customer Portal Configuration
      summary: Get customer portal settings
      description: >-
        Retrieves customer portal configuration settings for the authenticated
        shop. These settings control the appearance, behavior, and text labels
        displayed in the customer self-service portal.


        **Key Settings Returned:**

        - **UI Text Labels**: Button text, form field labels, messages, tooltips

        - **Feature Toggles**: Enable/disable portal features (shipping address
        edit, pause/resume, etc.)

        - **Branding**: Custom HTML for header/footer, date formats,
        localization

        - **Cancellation Controls**: Minimum days before cancellation, retention
        discounts

        - **Address Management**: Shipping address field labels and
        configurations

        - **Discount Display**: Discount note titles and descriptions for
        different cycles

        - **Product Management**: Add product labels, variant change text,
        quantity controls

        - **Order Management**: Order history labels, fulfillment status text

        - **Pause/Resume**: Pause badge text, resume subscription messages

        - **Rewards Integration**: Rewards text and points display labels


        **Common Use Cases:**

        - Retrieve portal settings for display in custom integrations

        - Sync portal configuration with external systems

        - Build custom customer portal interfaces using API-driven configuration

        - Validate current portal settings programmatically

        - Implement multi-language support by fetching localized labels


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getCustomerPortalSettingsV2
      parameters:
        - name: id
          in: path
          description: Shop identifier (typically shop domain)
          required: true
          schema:
            type: string
          example: mystore.myshopify.com
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          description: >-
            API Key for authentication (Preferred method - use this instead of
            api_key parameter)
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Customer portal settings successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerPortalSettingsDTO'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/CustomerPortalSettingsDTO'
        '404':
          description: Customer portal settings not found for shop
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/CustomerPortalSettingsDTO'
  /api/external/v2/customer-payments/token/{customerId}:
    get:
      tags:
        - Customer Payment Methods
      summary: Get customer payment token information
      description: >-
        Retrieves payment method token information for a specific customer. This
        endpoint returns the customer's stored payment tokens used for recurring
        subscription billing.


        **Key Information Returned:**

        - **Customer ID**: Shopify customer identifier

        - **Payment Tokens**: List of stored payment method tokens

        - **Payment Method Details**: Last 4 digits, card type, expiration

        - **Default Payment Method**: Primary payment method for subscriptions

        - **Token Status**: Active, expired, or failed payment methods

        - **Payment Gateway**: Stripe, Shopify Payments, etc.


        **Payment Token Information:**

        - **Token ID**: Unique identifier for the payment method

        - **Card Brand**: Visa, Mastercard, Amex, etc.

        - **Last 4 Digits**: Masked card number ending

        - **Expiry Date**: Card expiration month and year

        - **Billing Address**: Associated billing address details

        - **Created Date**: When payment method was added


        **Use Cases:**

        - Display saved payment methods in customer portal

        - Validate payment method availability before billing

        - Allow customers to select from existing payment methods

        - Sync payment data with external CRM or billing systems

        - Build custom payment management interfaces

        - Trigger payment update reminders for expiring cards


        **Security Note:** This endpoint only returns tokenized payment
        information. Full card numbers are never exposed via the API.


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getCustomerTokenV2
      parameters:
        - name: customerId
          in: path
          description: Shopify customer ID
          required: true
          schema:
            type: integer
            format: int64
          example: 123456789
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          description: >-
            API Key for authentication (Preferred method - use this instead of
            api_key parameter)
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Customer payment token information successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerTokenInfo'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/CustomerTokenInfo'
        '403':
          description: Access forbidden - customer does not belong to authenticated shop
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/CustomerTokenInfo'
        '404':
          description: Customer not found or has no payment methods
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/CustomerTokenInfo'
  /api/external/v2/customer-discount-code-infos/get-past-discounts:
    get:
      tags:
        - Customer Discount History
      summary: Get past discount codes for contract
      description: >-
        Retrieves historical discount codes that have been applied to or are
        associated with a specific membership contract. Returns discount details
        including code, value, usage limits, and expiration dates from Shopify.


        **Use Cases:**

        - Display discount history in customer portal

        - Show applied promotional codes

        - Track discount redemption for analytics

        - Verify discount eligibility


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getCustomerDiscountDetailsV2
      parameters:
        - name: contractId
          in: query
          description: Subscription contract ID
          required: true
          schema:
            type: integer
            format: int64
          example: 123456
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Discount history successfully retrieved
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Node'
        '401':
          description: Authentication required
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Node'
        '403':
          description: Access forbidden
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Node'
        '404':
          description: Contract not found
          content:
            '*/*':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Node'
  /api/external/v2/cancellation-managements/{id}:
    get:
      tags:
        - Cancellation Flow Configuration
      summary: Get cancellation flow configuration
      description: >-
        Retrieves the cancellation management settings for the shop, controlling
        how members cancel subscriptions. These settings define the cancellation
        experience including retention offers, surveys, and confirmation flows.


        **Key Configuration Returned:**

        - **Cancellation Reasons**: Predefined list of reasons members can
        select

        - **Retention Offers**: Discounts or perks offered to prevent
        cancellations

        - **Survey Questions**: Custom questions to gather cancellation feedback

        - **Confirmation Settings**: Text and buttons for cancel confirmation
        screen

        - **Minimum Cycle Requirements**: Enforce minimum subscription duration
        before canceling

        - **Win-Back Campaigns**: Settings for re-engagement after cancellation

        - **Plan-Specific Rules**: Different cancellation flows per membership
        plan


        **Cancellation Flow Elements:**

        - **Reason Selection**: Dropdown/radio options for why member is
        canceling

        - **Feedback Collection**: Open-text fields for additional comments

        - **Retention Step**: Show special offers before final cancellation

        - **Alternative Options**: Pause, skip, or frequency change suggestions

        - **Confirmation Screen**: Final confirmation with cancel button text

        - **Email Notifications**: Trigger cancellation confirmation emails


        **Retention Offer Configuration:**

        - Discount percentage or fixed amount off

        - Number of cycles the retention discount applies

        - Eligibility rules (new members only, all members, etc.)

        - Display message and call-to-action text

        - Success/failure handling


        **Use Cases:**

        - Build custom cancellation flows in member portals

        - Display retention offers programmatically

        - Integrate cancellation reasons with analytics platforms

        - Customize cancel experience per membership tier

        - Show plan-specific retention messaging

        - Enforce business rules around cancellations


        **Common Cancellation Reasons:**

        - Too expensive

        - No longer need the product

        - Delivery issues

        - Product quality concerns

        - Switching to competitor

        - Moving/relocating


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: getCancellationManagementV2
      parameters:
        - name: id
          in: path
          description: Shop identifier (typically shop domain)
          required: true
          schema:
            type: integer
            format: int64
          example: mystore.myshopify.com
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Cancellation flow configuration successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CancellationManagementDTO'
        '401':
          description: Authentication required - invalid or missing API key
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/CancellationManagementDTO'
        '404':
          description: Cancellation management configuration not found for shop
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/CancellationManagementDTO'
  /api/external/v2/subscription-customers/sync-info/{customerId}:
    delete:
      tags:
        - Membership Contracts
      operationId: syncCustomerInfoV2
      parameters:
        - name: customerId
          in: path
          required: true
          schema:
            type: integer
            format: int64
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
      responses:
        '200':
          description: OK
  /api/external/v2/subscription-contracts/{id}:
    delete:
      tags:
        - Membership Contracts
      summary: Cancel membership/subscription contract
      description: >-
        Cancels a membership/subscription contract and sends cancellation
        confirmation emails. This endpoint terminates the recurring subscription
        and processes all cancellation workflows.


        **Cancellation Process:**

        - **Contract Termination**: Marks subscription as cancelled in Shopify

        - **Billing Stop**: Prevents future billing attempts

        - **Email Notification**: Sends cancellation confirmation to customer

        - **Activity Logging**: Records cancellation event with source and
        feedback

        - **Feedback Capture**: Optional cancellation reason for analytics


        **Key Features:**

        - **Immediate Cancellation**: Stops subscription processing immediately

        - **Feedback Collection**: Capture customer cancellation reasons

        - **Automated Emails**: Customer receives cancellation confirmation

        - **Activity Tracking**: Logs cancellation to activity history

        - **Source Attribution**: Tracks whether cancellation came from customer
        portal or API


        **Validation Checks:**

        - **Contract Ownership**: Verifies contract belongs to authenticated
        shop

        - **Minimum Cycles**: Checks if minimum billing cycles requirement is
        met (if configured)

        - **Freeze Status**: Validates subscription is not frozen

        - **Existing Status**: Ensures contract is not already cancelled


        **Email Notifications:**

        - Sends cancellation confirmation to customer email

        - Includes subscription details and cancellation date

        - Uses customizable email templates from shop settings


        **Use Cases:**

        - Allow customers to cancel from custom portals or mobile apps

        - Bulk cancellation workflows via external systems

        - Integration with customer service platforms

        - Automated cancellation based on business rules

        - Churn management and retention workflows


        **Authentication:** Requires API key authentication via X-API-Key header
        or api_key parameter
      operationId: deleteSubscriptionContractV2
      parameters:
        - name: id
          in: path
          description: Membership contract ID to cancel
          required: true
          schema:
            type: integer
            format: int64
          example: 123456789
        - name: api_key
          in: query
          description: API Key (Deprecated - Use Header X-API-Key instead)
          required: false
          schema:
            type: string
        - name: X-API-Key
          in: header
          required: false
          schema:
            type: string
        - name: cancellationFeedback
          in: query
          description: Optional cancellation reason/feedback from customer
          required: false
          schema:
            type: string
          example: Too expensive
      responses:
        '204':
          description: Subscription successfully cancelled, confirmation email sent
        '400':
          description: >-
            Cancellation not allowed (minimum cycles not met, contract frozen,
            etc.)
          content:
            application/json:
              example:
                title: Bad Request
                status: 400
                detail: >-
                  This membership requires 3 minimum billing cycles before
                  cancellation
                errorKey: min_cycles_not_met
        '401':
          description: Authentication required - invalid or missing API key
        '404':
          description: Subscription contract not found
        '500':
          description: Shopify API error or email sending failure
components:
  schemas:
    ChangeShippingAddressVM:
      type: object
      properties:
        address1:
          type: string
        address2:
          type: string
        city:
          type: string
        firstName:
          type: string
        lastName:
          type: string
        phone:
          type: string
        province:
          type: string
        zip:
          type: string
        country:
          type: string
        countryCode:
          type: string
        provinceCode:
          type: string
        company:
          type: string
    Anchor:
      type: object
      properties:
        get__typename:
          type: string
        cutoffDay:
          type: integer
          format: int32
        day:
          type: integer
          format: int32
        month:
          type: integer
          format: int32
        type:
          type: string
          enum:
            - WEEKDAY
            - MONTHDAY
            - YEARDAY
            - $UNKNOWN
    Anchor1:
      type: object
      properties:
        get__typename:
          type: string
        cutoffDay:
          type: integer
          format: int32
        day:
          type: integer
          format: int32
        month:
          type: integer
          format: int32
        type:
          type: string
          enum:
            - WEEKDAY
            - MONTHDAY
            - YEARDAY
            - $UNKNOWN
    BillingAttempts:
      type: object
      properties:
        get__typename:
          type: string
        nodes:
          type: array
          items:
            $ref: '#/components/schemas/Node3'
    BillingPolicy:
      type: object
      properties:
        get__typename:
          type: string
        interval:
          type: string
          enum:
            - DAY
            - WEEK
            - MONTH
            - YEAR
            - $UNKNOWN
        intervalCount:
          type: integer
          format: int32
        anchors:
          type: array
          items:
            $ref: '#/components/schemas/Anchor'
        maxCycles:
          type: integer
          format: int32
        minCycles:
          type: integer
          format: int32
    CustomAttribute1:
      type: object
      properties:
        get__typename:
          type: string
        key:
          type: string
        value:
          type: string
    Customer:
      type: object
      properties:
        get__typename:
          type: string
        id:
          type: string
        email:
          type: string
          deprecated: true
        displayName:
          type: string
        firstName:
          type: string
        lastName:
          type: string
        phone:
          type: string
          deprecated: true
    CustomerPaymentMethod:
      type: object
      properties:
        get__typename:
          type: string
        id:
          type: string
        instrument:
          $ref: '#/components/schemas/Instrument'
        revokedAt:
          type: object
        revokedReason:
          type: string
          enum:
            - AUTHORIZE_NET_GATEWAY_NOT_ENABLED
            - AUTHORIZE_NET_RETURNED_NO_PAYMENT_METHOD
            - FAILED_TO_UPDATE_CREDIT_CARD
            - STRIPE_API_AUTHENTICATION_ERROR
            - STRIPE_API_INVALID_REQUEST_ERROR
            - STRIPE_GATEWAY_NOT_ENABLED
            - STRIPE_RETURNED_NO_PAYMENT_METHOD
            - STRIPE_PAYMENT_METHOD_NOT_CARD
            - BRAINTREE_API_AUTHENTICATION_ERROR
            - BRAINTREE_GATEWAY_NOT_ENABLED
            - BRAINTREE_RETURNED_NO_PAYMENT_METHOD
            - BRAINTREE_PAYMENT_METHOD_NOT_CARD
            - PAYMENT_METHOD_VERIFICATION_FAILED
            - THREE_D_SECURE_FLOW_IN_VERIFICATION_NOT_IMPLEMENTED
            - MANUALLY_REVOKED
            - FAILED_TO_RETRIEVE_BILLING_ADDRESS
            - MERGED
            - CUSTOMER_REDACTED
            - TOO_MANY_CONSECUTIVE_FAILURES
            - CVV_ATTEMPTS_LIMIT_EXCEEDED
            - $UNKNOWN
    DeliveryMethod:
      type: object
      properties:
        get__typename:
          type: string
        id:
          type: string
        methodType:
          type: string
          enum:
            - SHIPPING
            - PICK_UP
            - NONE
            - RETAIL
            - LOCAL
            - PICKUP_POINT
            - $UNKNOWN
        serviceCode:
          type: string
        minDeliveryDateTime:
          type: object
        maxDeliveryDateTime:
          type: object
        additionalInformation:
          $ref: '#/components/schemas/AdditionalInformation'
        brandedPromise:
          $ref: '#/components/schemas/BrandedPromise'
    DeliveryPolicy:
      type: object
      properties:
        get__typename:
          type: string
        interval:
          type: string
          enum:
            - DAY
            - WEEK
            - MONTH
            - YEAR
            - $UNKNOWN
        intervalCount:
          type: integer
          format: int32
        anchors:
          type: array
          items:
            $ref: '#/components/schemas/Anchor1'
    DeliveryPrice:
      type: object
      properties:
        get__typename:
          type: string
        amount:
          type: object
        currencyCode:
          type: string
          enum:
            - USD
            - EUR
            - GBP
            - CAD
            - AFN
            - ALL
            - DZD
            - AOA
            - ARS
            - AMD
            - AWG
            - AUD
            - BBD
            - AZN
            - BDT
            - BSD
            - BHD
            - BIF
            - BYN
            - BZD
            - BMD
            - BTN
            - BAM
            - BRL
            - BOB
            - BWP
            - BND
            - BGN
            - MMK
            - KHR
            - CVE
            - KYD
            - XAF
            - CLP
            - CNY
            - COP
            - KMF
            - CDF
            - CRC
            - HRK
            - CZK
            - DKK
            - DJF
            - DOP
            - XCD
            - EGP
            - ERN
            - ETB
            - FKP
            - XPF
            - FJD
            - GIP
            - GMD
            - GHS
            - GTQ
            - GYD
            - GEL
            - GNF
            - HTG
            - HNL
            - HKD
            - HUF
            - ISK
            - INR
            - IDR
            - ILS
            - IRR
            - IQD
            - JMD
            - JPY
            - JEP
            - JOD
            - KZT
            - KES
            - KID
            - KWD
            - KGS
            - LAK
            - LVL
            - LBP
            - LSL
            - LRD
            - LYD
            - LTL
            - MGA
            - MKD
            - MOP
            - MWK
            - MVR
            - MRU
            - MXN
            - MYR
            - MUR
            - MDL
            - MAD
            - MNT
            - MZN
            - NAD
            - NPR
            - ANG
            - NZD
            - NIO
            - NGN
            - NOK
            - OMR
            - PAB
            - PKR
            - PGK
            - PYG
            - PEN
            - PHP
            - PLN
            - QAR
            - RON
            - RUB
            - RWF
            - WST
            - SHP
            - SAR
            - RSD
            - SCR
            - SLL
            - SGD
            - SDG
            - SOS
            - SYP
            - ZAR
            - KRW
            - SSP
            - SBD
            - LKR
            - SRD
            - SZL
            - SEK
            - CHF
            - TWD
            - THB
            - TJS
            - TZS
            - TOP
            - TTD
            - TND
            - TRY
            - TMT
            - UGX
            - UAH
            - AED
            - UYU
            - UZS
            - VUV
            - VES
            - VND
            - XOF
            - YER
            - ZMW
            - USDC
            - BYR
            - STD
            - STN
            - VED
            - VEF
            - XXX
            - $UNKNOWN
    Discounts:
      type: object
      properties:
        get__typename:
          type: string
        nodes:
          type: array
          items:
            $ref: '#/components/schemas/Node2'
        pageInfo:
          $ref: '#/components/schemas/PageInfo2'
    FulfillmentOrders:
      type: object
      properties:
        get__typename:
          type: string
        nodes:
          type: array
          items:
            $ref: '#/components/schemas/Node'
        pageInfo:
          $ref: '#/components/schemas/PageInfo2'
    Instrument:
      type: object
      properties:
        get__typename:
          type: string
    Lines:
      type: object
      properties:
        get__typename:
          type: string
        nodes:
          type: array
          items:
            $ref: '#/components/schemas/Node'
        pageInfo:
          $ref: '#/components/schemas/PageInfo'
    Node:
      type: object
      properties:
        get__typename:
          type: string
    Node2:
      type: object
      properties:
        get__typename:
          type: string
        createdAt:
          type: object
        deliveredAt:
          type: object
        displayStatus:
          type: string
          enum:
            - ATTEMPTED_DELIVERY
            - CANCELED
            - CONFIRMED
            - DELAYED
            - DELIVERED
            - FAILURE
            - FULFILLED
            - CARRIER_PICKED_UP
            - IN_TRANSIT
            - LABEL_PRINTED
            - LABEL_PURCHASED
            - LABEL_VOIDED
            - MARKED_AS_FULFILLED
            - NOT_DELIVERED
            - OUT_FOR_DELIVERY
            - READY_FOR_PICKUP
            - PICKED_UP
            - SUBMITTED
            - $UNKNOWN
        estimatedDeliveryAt:
          type: object
        id:
          type: string
        inTransitAt:
          type: object
        name:
          type: string
        requiresShipping:
          type: boolean
        status:
          type: string
          enum:
            - PENDING
            - OPEN
            - SUCCESS
            - CANCELLED
            - ERROR
            - FAILURE
            - $UNKNOWN
        service:
          $ref: '#/components/schemas/Service'
        trackingInfo:
          type: array
          items:
            $ref: '#/components/schemas/TrackingInfo'
    Node3:
      type: object
      properties:
        get__typename:
          type: string
        completedAt:
          type: object
        createdAt:
          type: object
        id:
          type: string
        idempotencyKey:
          type: string
        ready:
          type: boolean
    OriginOrder:
      type: object
      properties:
        get__typename:
          type: string
        id:
          type: string
        name:
          type: string
        fulfillmentOrders:
          $ref: '#/components/schemas/FulfillmentOrders'
    PageInfo:
      type: object
      properties:
        get__typename:
          type: string
        hasPreviousPage:
          type: boolean
        hasNextPage:
          type: boolean
        startCursor:
          type: string
        endCursor:
          type: string
    PageInfo2:
      type: object
      properties:
        get__typename:
          type: string
        hasPreviousPage:
          type: boolean
        hasNextPage:
          type: boolean
        startCursor:
          type: string
        endCursor:
          type: string
    SubscriptionContract:
      type: object
      properties:
        get__typename:
          type: string
        id:
          type: string
        createdAt:
          type: object
        updatedAt:
          type: object
        nextBillingDate:
          type: object
        status:
          type: string
          enum:
            - ACTIVE
            - PAUSED
            - CANCELLED
            - EXPIRED
            - FAILED
            - $UNKNOWN
        deliveryPrice:
          $ref: '#/components/schemas/DeliveryPrice'
        lastPaymentStatus:
          type: string
          enum:
            - SUCCEEDED
            - FAILED
            - $UNKNOWN
        billingPolicy:
          $ref: '#/components/schemas/BillingPolicy'
        deliveryPolicy:
          $ref: '#/components/schemas/DeliveryPolicy'
        lines:
          $ref: '#/components/schemas/Lines'
        customerPaymentMethod:
          $ref: '#/components/schemas/CustomerPaymentMethod'
        deliveryMethod:
          $ref: '#/components/schemas/DeliveryMethod'
        originOrder:
          $ref: '#/components/schemas/OriginOrder'
        customer:
          $ref: '#/components/schemas/Customer'
        discounts:
          $ref: '#/components/schemas/Discounts'
        note:
          type: string
        customAttributes:
          type: array
          items:
            $ref: '#/components/schemas/CustomAttribute1'
        billingAttempts:
          $ref: '#/components/schemas/BillingAttempts'
    AttributeInfo:
      type: object
      properties:
        key:
          type: string
        value:
          type: string
    SubscriptionContractOneOffDTO:
      required:
        - shop
      type: object
      properties:
        id:
          type: integer
          format: int64
        shop:
          type: string
        billingAttemptId:
          type: integer
          format: int64
        subscriptionContractId:
          type: integer
          format: int64
        variantId:
          type: integer
          format: int64
        variantHandle:
          type: string
    Attributes:
      type: object
    Cart:
      type: object
      properties:
        token:
          type: string
        note:
          type: object
        attributes:
          $ref: '#/components/schemas/Attributes'
        original_total_price:
          type: integer
          format: int64
        total_price:
          type: integer
          format: int64
        total_discount:
          type: integer
          format: int64
        total_weight:
          type: integer
          format: int64
        item_count:
          type: integer
          format: int64
        items:
          type: array
          items:
            $ref: '#/components/schemas/Item'
        requires_shipping:
          type: boolean
        currency:
          type: string
        items_subtotal_price:
          type: integer
          format: int64
        cart_level_discount_applications:
          type: array
          items:
            type: object
    DiscountCodeRequest:
      type: object
      properties:
        cart:
          $ref: '#/components/schemas/Cart'
    FeaturedImage:
      type: object
      properties:
        aspect_ratio:
          type: integer
          format: int64
        alt:
          type: string
        height:
          type: integer
          format: int64
        url:
          type: string
        width:
          type: integer
          format: int64
    Item:
      type: object
      properties:
        id:
          type: integer
          format: int64
        properties:
          $ref: '#/components/schemas/Properties'
        quantity:
          type: integer
          format: int64
        variant_id:
          type: integer
          format: int64
        key:
          type: string
        title:
          type: string
        price:
          type: integer
          format: int64
        original_price:
          type: integer
          format: int64
        discounted_price:
          type: integer
          format: int64
        line_price:
          type: integer
          format: int64
        original_line_price:
          type: integer
          format: int64
        total_discount:
          type: integer
          format: int64
        discounts:
          type: array
          items:
            type: object
        sku:
          type: string
        grams:
          type: integer
          format: int64
        vendor:
          type: string
        taxable:
          type: boolean
        product_id:
          type: integer
          format: int64
        product_has_only_default_variant:
          type: boolean
        gift_card:
          type: boolean
        final_price:
          type: integer
          format: int64
        final_line_price:
          type: integer
          format: int64
        url:
          type: string
        featured_image:
          $ref: '#/components/schemas/FeaturedImage'
        image:
          type: string
        handle:
          type: string
        requires_shipping:
          type: boolean
        product_type:
          type: string
        product_title:
          type: string
        product_description:
          type: string
        variant_title:
          type: object
        variant_options:
          type: array
          items:
            type: string
        options_with_values:
          type: array
          items:
            $ref: '#/components/schemas/OptionsWithValue'
        line_level_discount_allocations:
          type: array
          items:
            type: object
        line_level_total_discount:
          type: integer
          format: int64
    OptionsWithValue:
      type: object
      properties:
        name:
          type: string
        value:
          type: string
    Properties:
      type: object
    DiscountCodeResponse:
      type: object
      properties:
        discountCode:
          type: string
        errorMessage:
          type: string
        discountNeeded:
          type: boolean
    SubscriptionBillingAttemptDTO:
      required:
        - retryingNeeded
        - shop
      type: object
      properties:
        id:
          type: integer
          format: int64
        shop:
          type: string
        billingAttemptId:
          type: string
        status:
          type: string
          enum:
            - SUCCESS
            - FAILURE
            - REQUESTING
            - PROGRESS
            - QUEUED
            - SKIPPED
            - SOCIAL_CONNECTION_NULL
            - CONTRACT_CANCELLED
            - CONTRACT_ENDED
            - CONTRACT_PAUSED
            - AUTO_CHARGE_DISABLED
            - SKIPPED_DUNNING_MGMT
            - SECURITY_CHALLENGE
            - SHOPIFY_EXCEPTION
        billingDate:
          type: string
          format: date-time
        contractId:
          type: integer
          format: int64
        attemptCount:
          type: integer
          format: int32
        attemptTime:
          type: string
          format: date-time
        graphOrderId:
          type: string
        orderId:
          type: integer
          format: int64
        orderAmount:
          type: number
          format: double
        orderName:
          type: string
        retryingNeeded:
          type: boolean
        transactionFailedEmailSentStatus:
          type: string
          enum:
            - SENT
            - UNSENT
            - FAILED
            - EMAIL_SETTINGS_DISABLED
            - CUSTOMER_PAYMENT_EMPTY
            - CONTRACT_CANCELLED
        upcomingOrderEmailSentStatus:
          type: string
          enum:
            - SENT
            - UNSENT
            - FAILED
            - EMAIL_SETTINGS_DISABLED
            - CUSTOMER_PAYMENT_EMPTY
            - CONTRACT_CANCELLED
            - STOP_FROM_CONTRACT
            - CONTRACT_PAUSED
        applyUsageCharge:
          type: boolean
        recurringChargeId:
          type: integer
          format: int64
        transactionRate:
          type: number
          format: double
        usageChargeStatus:
          type: string
          enum:
            - SUCCESS
            - FAILED
            - TO_BE_TRIED
        transactionFailedSmsSentStatus:
          type: string
          enum:
            - SENT
            - UNSENT
            - FAILED
            - SMS_SETTINGS_DISABLED
            - CUSTOMER_PAYMENT_EMPTY
            - CONTRACT_CANCELLED
            - PHONE_NUMBER_EMPTY
        upcomingOrderSmsSentStatus:
          type: string
          enum:
            - SENT
            - UNSENT
            - FAILED
            - SMS_SETTINGS_DISABLED
            - CUSTOMER_PAYMENT_EMPTY
            - CONTRACT_CANCELLED
            - STOP_FROM_CONTRACT
            - CONTRACT_PAUSED
            - PHONE_NUMBER_EMPTY
        billingAttemptResponseMessage:
          type: string
        progressAttemptCount:
          type: integer
          format: int32
        orderNote:
          type: string
        variantList:
          type: array
          items:
            $ref: '#/components/schemas/VariantQuantity'
        orderAmountUSD:
          type: number
          format: double
        securityChallengeSentStatus:
          type: string
          enum:
            - SENT
            - UNSENT
            - FAILED
            - EMAIL_SETTINGS_DISABLED
            - CONTRACT_CANCELLED
        upgradeDowngradeBilling:
          type: boolean
    VariantQuantity:
      type: object
      properties:
        variantId:
          type: integer
          format: int64
        quantity:
          type: integer
          format: int32
        title:
          type: string
        image:
          type: string
        productTitle:
          type: string
        productId:
          type: string
        sellingPlanId:
          type: string
    VariantQuantityInfo:
      type: object
      properties:
        variantQuantityList:
          type: array
          items:
            $ref: '#/components/schemas/VariantQuantity'
    CountryInfo:
      type: object
      properties:
        shouldIncludeAllProvince:
          type: boolean
        code:
          type: string
        deliveryMethodInfo:
          type: array
          items:
            $ref: '#/components/schemas/DeliveryMethodInfo'
        restOfWorld:
          type: boolean
        provinceCode:
          type: string
    CreateShippingProfileRequestV2:
      type: object
      properties:
        name:
          type: string
        locationInfos:
          type: array
          items:
            $ref: '#/components/schemas/LocationInfo'
    DeliveryMethodInfo:
      type: object
      properties:
        amount:
          type: number
          format: double
        currencyCode:
          type: string
          enum:
            - USD
            - EUR
            - GBP
            - CAD
            - AFN
            - ALL
            - DZD
            - AOA
            - ARS
            - AMD
            - AWG
            - AUD
            - BBD
            - AZN
            - BDT
            - BSD
            - BHD
            - BIF
            - BYN
            - BZD
            - BMD
            - BTN
            - BAM
            - BRL
            - BOB
            - BWP
            - BND
            - BGN
            - MMK
            - KHR
            - CVE
            - KYD
            - XAF
            - CLP
            - CNY
            - COP
            - KMF
            - CDF
            - CRC
            - HRK
            - CZK
            - DKK
            - DJF
            - DOP
            - XCD
            - EGP
            - ERN
            - ETB
            - FKP
            - XPF
            - FJD
            - GIP
            - GMD
            - GHS
            - GTQ
            - GYD
            - GEL
            - GNF
            - HTG
            - HNL
            - HKD
            - HUF
            - ISK
            - INR
            - IDR
            - ILS
            - IRR
            - IQD
            - JMD
            - JPY
            - JEP
            - JOD
            - KZT
            - KES
            - KID
            - KWD
            - KGS
            - LAK
            - LVL
            - LBP
            - LSL
            - LRD
            - LYD
            - LTL
            - MGA
            - MKD
            - MOP
            - MWK
            - MVR
            - MRU
            - MXN
            - MYR
            - MUR
            - MDL
            - MAD
            - MNT
            - MZN
            - NAD
            - NPR
            - ANG
            - NZD
            - NIO
            - NGN
            - NOK
            - OMR
            - PAB
            - PKR
            - PGK
            - PYG
            - PEN
            - PHP
            - PLN
            - QAR
            - RON
            - RUB
            - RWF
            - WST
            - SHP
            - SAR
            - RSD
            - SCR
            - SLL
            - SGD
            - SDG
            - SOS
            - SYP
            - ZAR
            - KRW
            - SSP
            - SBD
            - LKR
            - SRD
            - SZL
            - SEK
            - CHF
            - TWD
            - THB
            - TJS
            - TZS
            - TOP
            - TTD
            - TND
            - TRY
            - TMT
            - UGX
            - UAH
            - AED
            - UYU
            - UZS
            - VUV
            - VES
            - VND
            - XOF
            - YER
            - ZMW
            - USDC
            - BYR
            - STD
            - STN
            - VED
            - VEF
            - XXX
            - $UNKNOWN
        carrierServiceId:
          type: string
        name:
          type: string
        priceConditions:
          type: array
          items:
            $ref: '#/components/schemas/PriceCondition'
        weightConditions:
          type: array
          items:
            $ref: '#/components/schemas/WeightCondition'
    LocationInfo:
      type: object
      properties:
        locationId:
          type: string
        countryInfos:
          type: array
          items:
            $ref: '#/components/schemas/CountryInfo'
    PriceCondition:
      type: object
      properties:
        amount:
          type: number
          format: double
        deliverCondtion:
          type: string
    WeightCondition:
      type: object
      properties:
        deliveryCondition:
          type: string
        weight:
          type: number
          format: double
        weightUnit:
          type: string
    DeliveryProfileDTO:
      required:
        - deliveryProfileId
        - shop
      type: object
      properties:
        id:
          type: integer
          format: int64
        shop:
          type: string
        deliveryProfileId:
          type: string
        sellerGroupIds:
          uniqueItems: true
          type: array
          items:
            type: string
        name:
          type: string
    CreateShippingProfileRequestVM:
      type: object
      properties:
        name:
          type: string
        id:
          type: integer
          format: int64
        deliveryMethodInfo:
          type: array
          items:
            $ref: '#/components/schemas/DeliveryMethodInfo'
        countryInfos:
          type: array
          items:
            $ref: '#/components/schemas/DeliveryCountryInfo'
        locationInfos:
          type: array
          items:
            $ref: '#/components/schemas/LocationInfo'
        restOfWorld:
          type: boolean
    DeliveryCountryInfo:
      type: object
      properties:
        code:
          type: string
        restOfWorld:
          type: boolean
        provinceCode:
          type: string
        shouldIncludeAllProvince:
          type: boolean
    FrequencyInfoDTO:
      type: object
      properties:
        frequencyCount:
          type: integer
          format: int32
        frequencyInterval:
          type: string
          enum:
            - DAY
            - WEEK
            - MONTH
            - YEAR
        billingFrequencyCount:
          type: integer
          format: int32
        billingFrequencyInterval:
          type: string
          enum:
            - DAY
            - WEEK
            - MONTH
            - YEAR
        frequencyName:
          type: string
        discountOffer:
          type: number
          format: double
        discountOffer2:
          type: number
          format: double
        afterCycle1:
          type: integer
          format: int32
        afterCycle2:
          type: integer
          format: int32
        discountType:
          type: string
          enum:
            - PERCENTAGE
            - FIXED
            - PRICE
        discountType2:
          type: string
          enum:
            - PERCENTAGE
            - FIXED
            - PRICE
        discountEnabled:
          type: boolean
        discountEnabled2:
          type: boolean
        discountEnabledMasked:
          type: boolean
        discountEnabled2Masked:
          type: boolean
        id:
          type: string
        frequencyType:
          type: string
          enum:
            - ON_PURCHASE_DAY
            - ON_SPECIFIC_DAY
        specificDayValue:
          type: integer
          format: int32
        specificMonthValue:
          type: integer
          format: int32
        specificDayEnabled:
          type: boolean
        maxCycles:
          type: integer
          format: int32
        minCycles:
          type: integer
          format: int32
        cutOff:
          type: integer
          format: int32
        prepaidFlag:
          type: string
        idNew:
          type: string
        planType:
          type: string
          enum:
            - PAY_AS_YOU_GO
            - PREPAID
            - ADVANCED_PREPAID
        deliveryPolicyPreAnchorBehavior:
          type: string
          enum:
            - ASAP
            - NEXT
            - $UNKNOWN
        freeTrialEnabled:
          type: boolean
        freeTrialCount:
          type: integer
          format: int32
        freeTrialInterval:
          type: string
          enum:
            - DAY
            - WEEK
            - MONTH
            - YEAR
        frequencyDescription:
          type: string
        keepOriginalNextBillingDateAfterTrial:
          type: boolean
        planSequence:
          type: integer
          format: int32
        groupName:
          type: string
        groupId:
          type: integer
          format: int64
        memberOnly:
          type: boolean
        nonMemberOnly:
          type: boolean
        memberInclusiveTags:
          type: string
        memberExclusiveTags:
          type: string
        lifeTimeMembership:
          type: boolean
        rulesJson:
          type: string
    SubscriptionGroupV2DTO:
      type: object
      properties:
        id:
          type: integer
          format: int64
        productCount:
          type: integer
          format: int64
        productVariantCount:
          type: integer
          format: int64
        subscriptionPlans:
          type: array
          items:
            $ref: '#/components/schemas/FrequencyInfoDTO'
        groupName:
          type: string
        productIds:
          type: string
        productId:
          type: string
        variantIds:
          type: string
        accessoryProductIds:
          type: string
        customerTag:
          type: string
        orderTag:
          type: string
        rulesJson:
          type: string
        formFieldsJson:
          type: string
        memberOrderTag:
          type: string
    SubscriptionContractDetailsDTO:
      required:
        - shop
      type: object
      properties:
        id:
          type: integer
          format: int64
        shop:
          type: string
        graphSubscriptionContractId:
          type: string
        subscriptionContractId:
          type: integer
          format: int64
        billingPolicyInterval:
          type: string
        billingPolicyIntervalCount:
          type: integer
          format: int32
        currencyCode:
          type: string
        customerId:
          type: integer
          format: int64
        graphCustomerId:
          type: string
        deliveryPolicyInterval:
          type: string
        deliveryPolicyIntervalCount:
          type: integer
          format: int32
        status:
          type: string
        graphOrderId:
          type: string
        orderId:
          type: integer
          format: int64
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        nextBillingDate:
          type: string
          format: date-time
        orderAmount:
          type: number
          format: double
        orderName:
          type: string
        customerName:
          type: string
        customerEmail:
          type: string
        subscriptionCreatedEmailSent:
          type: boolean
        endsAt:
          type: string
          format: date-time
        startsAt:
          type: string
          format: date-time
        subscriptionCreatedEmailSentStatus:
          type: string
          enum:
            - SENT
            - UNSENT
            - FAILED
            - EMAIL_SETTINGS_DISABLED
            - CUSTOMER_PAYMENT_EMPTY
            - CONTRACT_PAUSED_STATUS
        minCycles:
          type: integer
          format: int32
        maxCycles:
          type: integer
          format: int32
        customerFirstName:
          type: string
        customerLastName:
          type: string
        autoCharge:
          type: boolean
        importedId:
          type: string
        stopUpComingOrderEmail:
          type: boolean
        pausedFromActive:
          type: boolean
        subscriptionCreatedSmsSentStatus:
          type: string
          enum:
            - SENT
            - UNSENT
            - FAILED
            - SMS_SETTINGS_DISABLED
            - CUSTOMER_PAYMENT_EMPTY
            - CONTRACT_PAUSED_STATUS
            - PHONE_NUMBER_EMPTY
        phone:
          type: string
        activatedOn:
          type: string
          format: date-time
        pausedOn:
          type: string
          format: date-time
        cancelledOn:
          type: string
          format: date-time
        contractDetailsJSON:
          type: string
        cancellationFeedback:
          type: string
        orderNote:
          type: string
        orderNoteAttributes:
          type: string
        allowDeliveryPriceOverride:
          type: boolean
        orderAmountUSD:
          type: number
          format: double
        billingDateAfterTrial:
          type: string
          format: date-time
        trialEndDate:
          type: string
          format: date-time
        pausedBySecurityChallenge:
          type: boolean
        dunning:
          type: boolean
        contractAmount:
          type: number
          format: double
        contractAmountUSD:
          type: number
          format: double
        upcomingSwapRule:
          type: string
        emailBouncedOrFailed:
          type: boolean
    SubscriptionCustomCssDTO:
      required:
        - shop
      type: object
      properties:
        id:
          type: integer
          format: int64
        shop:
          type: string
        customCss:
          type: string
        customerPoratlCSS:
          type: string
        bundlingCSS:
          type: string
        bundlingIframeCSS:
          type: string
    Pageable:
      type: object
      properties:
        page:
          minimum: 0
          type: integer
          format: int32
        size:
          minimum: 1
          type: integer
          format: int32
        sort:
          type: array
          items:
            type: string
    ScheduledDowngradeRequest:
      type: object
      properties:
        shop:
          type: string
        contractId:
          type: integer
          format: int64
        waitTillTimestamp:
          type: string
        oldLineId:
          type: string
        oldVariantId:
          type: string
        newVariantId:
          type: string
        sellingPlanId:
          type: string
        sellingPlanName:
          type: string
        oldPrice:
          type: number
          format: double
        newPrice:
          type: number
          format: double
        newCustomerTag:
          type: string
        oldCustomerTags:
          type: string
        newOrderTag:
          type: string
        eventSource:
          type: string
        retryCount:
          type: integer
          format: int32
        customerId:
          type: integer
          format: int64
        executionArn:
          type: string
    AdditionalInformation:
      type: object
      properties:
        get__typename:
          type: string
        instructions:
          type: string
    BrandedPromise:
      type: object
      properties:
        get__typename:
          type: string
        handle:
          type: string
        name:
          type: string
    Order:
      type: object
      properties:
        get__typename:
          type: string
        id:
          type: string
        fulfillmentOrders:
          $ref: '#/components/schemas/FulfillmentOrders'
    Service:
      type: object
      properties:
        get__typename:
          type: string
        handle:
          type: string
        serviceName:
          type: string
        type:
          type: string
          enum:
            - GIFT_CARD
            - MANUAL
            - THIRD_PARTY
            - $UNKNOWN
    TrackingInfo:
      type: object
      properties:
        get__typename:
          type: string
        url:
          type: object
        number:
          type: string
        company:
          type: string
    ProductInfo:
      required:
        - shop
      type: object
      properties:
        id:
          type: integer
          format: int64
        shop:
          type: string
        productId:
          type: integer
          format: int64
        productTitle:
          type: string
        productHandle:
          type: string
    SubscriptionBundling:
      required:
        - shop
      type: object
      properties:
        id:
          type: integer
          format: int64
        shop:
          type: string
        subscriptionBundlingEnabled:
          type: boolean
        subscriptionId:
          type: integer
          format: int64
        minProductCount:
          type: integer
          format: int32
        maxProductCount:
          type: integer
          format: int32
        discount:
          type: number
          format: double
        uniqueRef:
          type: string
    SubscriptionBundlingResponse:
      type: object
      properties:
        bundle:
          $ref: '#/components/schemas/SubscriptionBundling'
        subscription:
          $ref: '#/components/schemas/SubscriptionGroupPlan'
        products:
          type: array
          items:
            $ref: '#/components/schemas/ProductInfo'
        variants:
          type: array
          items:
            type: string
    SubscriptionGroupPlan:
      required:
        - shop
      type: object
      properties:
        id:
          type: integer
          format: int64
        shop:
          type: string
        groupName:
          type: string
        subscriptionId:
          type: integer
          format: int64
        productCount:
          type: integer
          format: int32
        productVariantCount:
          type: integer
          format: int32
        infoJson:
          type: string
        productIds:
          type: string
        variantIds:
          type: string
        variantProductIds:
          type: string
        customerTag:
          type: string
        orderTag:
          type: string
        rulesJson:
          type: string
        formFieldsJson:
          type: string
        savedSearchId:
          type: string
        savedSegmentSearchId:
          type: string
        planSequence:
          type: integer
          format: int32
        memberOrderTag:
          type: string
    SubscriptionBundleSettingsDTO:
      required:
        - addButtonText
        - myDeliveryText
        - proceedToCheckoutButtonText
        - productsToProceedText
        - selectMinimumProductButtonText
        - selectedFrequencyLabelText
        - shop
      type: object
      properties:
        id:
          type: integer
          format: int64
        shop:
          type: string
        selectedFrequencyLabelText:
          type: string
        addButtonText:
          type: string
        selectMinimumProductButtonText:
          type: string
        productsToProceedText:
          type: string
        proceedToCheckoutButtonText:
          type: string
        myDeliveryText:
          type: string
        bundleTopHtml:
          type: string
        bundleBottomHtml:
          type: string
        failedToAddTitleText:
          type: string
        okBtnText:
          type: string
        failedToAddMsgText:
          type: string
        buttonColor:
          type: string
        backgroundColor:
          type: string
        pageBackgroundColor:
          type: string
        buttonBackgroundColor:
          type: string
        variantNotAvailable:
          type: string
        bundleRedirect:
          type: string
          enum:
            - CART
            - CHECKOUT
        isBundleWithoutScroll:
          type: boolean
        descriptionLength:
          type: integer
          format: int32
        currencySwitcherClassName:
          type: string
        productPriceFormatField:
          type: string
        productTitleFontColor:
          type: string
    TokenDetails:
      type: object
      properties:
        manageSubscriptionLink:
          type: string
        tokenExpirationTime:
          type: string
          format: date-time
    CustomerTokenInfo:
      type: object
      properties:
        customerId:
          type: integer
          format: int64
        token:
          type: string
    CustomerPortalSettingsDTO:
      required:
        - amountLbl
        - cancelAccordionTitle
        - cancelFreqBtnText
        - cancelSubscriptionBtnText
        - cardExpiryText
        - cardHolderNameText
        - cardLastFourDigitText
        - cardTypeText
        - editFrequencyBtnText
        - nextOrderDateLbl
        - nextOrderText
        - noSubscriptionMessage
        - orderFrequencyText
        - orderNoLbl
        - paymentDetailAccordionTitle
        - paymentInfoText
        - paymentMethodTypeText
        - quantityLbl
        - shop
        - statusLbl
        - statusText
        - subscriptionNoText
        - totalProductsText
        - upcomingOrderAccordionTitle
        - updateFreqBtnText
        - updatePaymentBtnText
        - updatePaymentMessage
      type: object
      properties:
        id:
          type: integer
          format: int64
        shop:
          type: string
        orderFrequencyText:
          type: string
        totalProductsText:
          type: string
        nextOrderText:
          type: string
        statusText:
          type: string
        cancelSubscriptionBtnText:
          type: string
        noSubscriptionMessage:
          type: string
        subscriptionNoText:
          type: string
        updatePaymentMessage:
          type: string
        cardLastFourDigitText:
          type: string
        cardExpiryText:
          type: string
        cardHolderNameText:
          type: string
        cardTypeText:
          type: string
        paymentMethodTypeText:
          type: string
        cancelAccordionTitle:
          type: string
        paymentDetailAccordionTitle:
          type: string
        upcomingOrderAccordionTitle:
          type: string
        paymentInfoText:
          type: string
        updatePaymentBtnText:
          type: string
        nextOrderDateLbl:
          type: string
        statusLbl:
          type: string
        quantityLbl:
          type: string
        amountLbl:
          type: string
        orderNoLbl:
          type: string
        editFrequencyBtnText:
          type: string
        cancelFreqBtnText:
          type: string
        updateFreqBtnText:
          type: string
        pauseResumeSub:
          type: boolean
        changeNextOrderDate:
          type: boolean
        cancelSub:
          type: boolean
        changeOrderFrequency:
          type: boolean
        createAdditionalOrder:
          type: boolean
        manageSubscriptionButtonText:
          type: string
        editChangeOrderBtnText:
          type: string
        cancelChangeOrderBtnText:
          type: string
        updateChangeOrderBtnText:
          type: string
        editProductButtonText:
          type: string
        deleteButtonText:
          type: string
        updateButtonText:
          type: string
        cancelButtonText:
          type: string
        addProductButtonText:
          type: string
        downgradeMembershipLabel:
          type: string
        addProductLabelText:
          type: string
        activeBadgeText:
          type: string
        closeBadgeText:
          type: string
        skipOrderButtonText:
          type: string
        productLabelText:
          type: string
        seeMoreDetailsText:
          type: string
        hideDetailsText:
          type: string
        productInSubscriptionText:
          type: string
        subTotalLabelText:
          type: string
        paymentNotificationText:
          type: string
        editProductFlag:
          type: boolean
        deleteProductFlag:
          type: boolean
        showShipment:
          type: boolean
        addAdditionalProduct:
          type: boolean
        successText:
          type: string
        cancelSubscriptionConfirmPrepaidText:
          type: string
        cancelSubscriptionConfirmPayAsYouGoText:
          type: string
        cancelSubscriptionPrepaidButtonText:
          type: string
        cancelSubscriptionPayAsYouGoButtonText:
          type: string
        upcomingFulfillmentText:
          type: string
        creditCardText:
          type: string
        endingWithText:
          type: string
        weekText:
          type: string
        dayText:
          type: string
        monthText:
          type: string
        yearText:
          type: string
        skipBadgeText:
          type: string
        queueBadgeText:
          type: string
        shippingLabelText:
          type: string
        address1LabelText:
          type: string
        address2LabelText:
          type: string
        companyLabelText:
          type: string
        cityLabelText:
          type: string
        countryLabelText:
          type: string
        firstNameLabelText:
          type: string
        lastNameLabelText:
          type: string
        phoneLabelText:
          type: string
        provinceLabelText:
          type: string
        zipLabelText:
          type: string
        addressHeaderTitleText:
          type: string
        changeShippingAddressFlag:
          type: boolean
        updateEditShippingButtonText:
          type: string
        cancelEditShippingButtonText:
          type: string
        pauseSubscriptionText:
          type: string
        resumeSubscriptionText:
          type: string
        pauseBadgeText:
          type: string
        customerPortalSettingJson:
          type: string
        discountNoteTitle:
          type: string
        initialDiscountNoteDescription:
          type: string
        afterCycleDiscountNoteDescription:
          type: string
        productRemovedTooltip:
          type: string
        deliveryPriceText:
          type: string
        shippingOptionText:
          type: string
        nextDeliveryDate:
          type: string
        everyLabelText:
          type: string
        orderNoteFlag:
          type: boolean
        orderNoteText:
          type: string
        useUrlWithCustomerId:
          type: boolean
        expiredTokenText:
          type: string
        portalLoginLinkText:
          type: string
        localeDate:
          type: string
        productSelectionOption:
          type: string
          enum:
            - ALL_PRODUCTS
            - PRODUCTS_FROM_ALL_PLANS
            - PRODUCTS_FROM_CURRENT_PLAN
        includeOutOfStockProduct:
          type: boolean
        customerIdText:
          type: string
        helloNameText:
          type: string
        goBackButtonText:
          type: string
        changeVariantLabelText:
          type: string
        provinceCodeLabelText:
          type: string
        countryCodeLabelText:
          type: string
        pleaseWaitLoaderText:
          type: string
        openBadgeText:
          type: string
        cancelSubscriptionMinimumBillingIterationsMessage:
          type: string
        topHtml:
          type: string
        bottomHtml:
          type: string
        updateShipmentBillingDate:
          type: boolean
        discountCodeText:
          type: string
        discountCodeApplyButtonText:
          type: string
        discountCode:
          type: boolean
        applySubscriptionDiscount:
          type: boolean
        subscriptionDiscountTypeUnit:
          type: string
          enum:
            - PERCENTAGE
            - AMOUNT
        subscriptionDiscount:
          type: number
          format: double
        upSellMessage:
          type: string
        freezeOrderTillMinCycle:
          type: boolean
        freezeUpdateSubscriptionMessage:
          type: string
        addOneTimeProduct:
          type: boolean
        selectProductLabelText:
          type: string
        purchaseOptionLabelText:
          type: string
        finishLabelText:
          type: string
        nextBtnText:
          type: string
        previousBtnText:
          type: string
        closeBtnText:
          type: string
        deleteConfirmationMsgText:
          type: string
        deleteMsgText:
          type: string
        yesBtnText:
          type: string
        noBtnText:
          type: string
        oneTimePurchaseNoteText:
          type: string
        clickHereText:
          type: string
        productAddMessageText:
          type: string
        choosePurchaseOptionLabelText:
          type: string
        oneTimePurchaseMessageText:
          type: string
        contractUpdateMessageText:
          type: string
        oneTimePurchaseDisplayMessageText:
          type: string
        addProductFinishedMessageText:
          type: string
        contractErrorMessageText:
          type: string
        addToSubscriptionTitleCP:
          type: string
        oneTimePurchaseTitleCP:
          type: string
        seeMoreProductBtnText:
          type: string
        totalPricePerDeliveryText:
          type: string
        fulfilledText:
          type: string
        dateFormat:
          type: string
        discountCouponAppliedText:
          type: string
        subscriptionPausedMessageText:
          type: string
        subscriptionActivatedMessageText:
          type: string
        unableToUpdateSubscriptionStatusMessageText:
          type: string
        selectCancellationReasonLabelText:
          type: string
        upcomingOrderChangePopupSuccessTitleText:
          type: string
        upcomingOrderChangePopupSuccessDescriptionText:
          type: string
        upcomingOrderChangePopupSuccessClosebtnText:
          type: string
        upcomingOrderChangePopupFailureTitleText:
          type: string
        upcomingOrderChangePopupFailureDescriptionText:
          type: string
        upcomingOrderChangePopupFailureClosebtnText:
          type: string
        viewAttributeLabelText:
          type: string
        attributeNameLabelText:
          type: string
        attributeValue:
          type: string
        addNewButtonText:
          type: string
        attributeHeadingText:
          type: string
        enableViewAttributes:
          type: boolean
        addProductOnlyForSameProductVariant:
          type: boolean
        enableMembershipHistory:
          type: boolean
        enableShowProductDescription:
          type: boolean
        descriptionLength:
          type: string
        historyLabelText:
          type: string
        orderNoLabelText:
          type: string
        orderDateLabelText:
          type: string
        lastAttemptDateLabelText:
          type: string
        membershipExpireText:
          type: string
        membershipExpireDescription:
          type: string
        discountRecurringCycleLimitOnCancellation:
          type: integer
          format: int32
        discountMessageOnCancellation:
          type: string
        conformationPopupForCancellationDiscountText:
          type: string
        enableResendMagicLink:
          type: boolean
        redeemRewardsText:
          type: string
        rewardsText:
          type: string
        yourRewardsText:
          type: string
        yourAvailableRewardsPointsText:
          type: string
        productReplaceWarningText:
          type: string
        additionalFeedbackLabel:
          type: string
        backToAccountLabel:
          type: string
        missedBillingAlertText:
          type: string
        acceptBtnText:
          type: string
        cancelledOnLabelText:
          type: string
        cancellationReasonLabelText:
          type: string
        cancellationFeedbackLabelText:
          type: string
        preventCancellationBeforeDaysMessage:
          type: string
        membershipSwap:
          type: string
          enum:
            - UPGRADE_ONLY
            - DOWNGRADE_ONLY
            - UPGRADE_AND_DOWNGRADE
            - NONE
        retrieveMagicLinkDescription:
          type: string
        retrieveMagicLinkText:
          type: string
        lastBillingAttemptFailedText:
          type: string
        preventCancellationBeforeDays:
          type: string
        allowCancellationBeforeDays:
          type: string
        enableRedirectMyAccountButton:
          type: boolean
        goBackRedirectLink:
          type: string
        resumeSub:
          type: boolean
        deliveryFrequencyLabelText:
          type: string
        deliverLabelText:
          type: string
        daysLabelText:
          type: string
        weeksLabelText:
          type: string
        monthsLabelText:
          type: string
        yearsLabelText:
          type: string
        removedTagOnFreeTrial:
          type: string
        chooseAnotherPaymentMethodText:
          type: string
        editShippingModalLabel:
          type: string
        continueButtonLabel:
          type: string
        selectDeliveryMethodLabel:
          type: string
        saveButtonLabel:
          type: string
        showUpcomingOrdersLabel:
          type: string
        shippingAddressLabel:
          type: string
        shippingMethodLabel:
          type: string
        subtotalLabel:
          type: string
        resumeMembershipLabel:
          type: string
        closeButtonLabel:
          type: string
        pauseMembershipLabel:
          type: string
        pauseMembershipMessageText:
          type: string
        noPaymentMethodFoundText:
          type: string
        membershipPerksDetailsText:
          type: string
        resumeSubscriptionDescriptionText:
          type: string
        skipFirstPage:
          type: boolean
        welcomeText:
          type: string
        removeButtonText:
          type: string
        productConfirmationButtonLabel:
          type: string
        editQuantityLabelText:
          type: string
    CancellationManagementDTO:
      required:
        - shop
      type: object
      properties:
        id:
          type: integer
          format: int64
        shop:
          type: string
        cancellationType:
          type: string
          enum:
            - CANCEL_IMMEDIATELY
            - CANCELLATION_INSTRUCTIONS
            - CUSTOMER_RETENTION_FLOW
        cancellationInstructionsText:
          type: string
        cancellationReasonsJSON:
          type: string
        cancellationRetentionMessage:
          type: string
        pauseDurationCycle:
          type: integer
          format: int32
        dynamicallyPauseCycleOnCancellation:
          type: boolean
        discountRecurringCycleLimit:
          type: integer
          format: int32
