> ## Documentation Index
> Fetch the complete documentation index at: https://developers.appstle.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get current billing cycle number for a subscription contract

> Retrieves the current billing cycle number for a specific subscription contract. The cycle number represents how many successful billing attempts have occurred for this subscription, starting from 1 for the initial order.

**What is a Billing Cycle?**
A billing cycle represents one completed billing period in a subscription's lifetime. Each successful billing attempt increments the cycle count. This number is crucial for:
- Tracking subscription progress towards minimum/maximum cycle limits
- Applying cycle-based pricing adjustments (discounts after N cycles)
- Determining eligibility for cancellation (minimum cycles requirement)
- Calculating customer lifetime value
- Analyzing subscription retention metrics

**How Cycle Counting Works:**

**Initial Order:**
- Cycle 1 starts when subscription is first created
- Initial order counts as the first billing cycle
- Includes origin order that created the subscription

**Subsequent Orders:**
- Each successful billing attempt increments cycle by 1
- Only SUCCESS status billing attempts are counted
- Failed/skipped billing attempts do NOT increment cycle
- Paused subscriptions maintain their current cycle number

**Calculation Formula:**
```
Current Cycle = 1 + (Number of Successful Billing Attempts)
```

**Example Timeline:**
- Day 1: Subscription created, initial order → Cycle 1
- Day 30: First recurring order successful → Cycle 2
- Day 60: Second recurring order successful → Cycle 3
- Day 90: Billing fails (payment declined) → Still Cycle 3
- Day 95: Retry successful → Cycle 4

**Use Cases:**

**1. Cancellation Eligibility:**
- Verify customer has met minimum cycle requirement
- Enforce contract terms (e.g., "3 month minimum")
- Display "Can cancel after N more orders" messaging
- Block premature cancellations

**2. Pricing Adjustments:**
- Apply introductory pricing for first N cycles
- Trigger loyalty discounts after X cycles
- Calculate when pricing changes take effect
- Implement "First 3 months 50% off" promotions

**3. Customer Retention:**
- Identify subscriptions at risky cycle counts
- Send retention campaigns at specific milestones
- Track average cycles before churn
- Celebrate subscription anniversaries

**4. Analytics & Reporting:**
- Calculate customer lifetime value (cycle × price)
- Analyze subscription duration distribution
- Track retention curves by cohort
- Measure success of lifecycle campaigns

**5. Customer Portal Display:**
- Show "Order #X of Y" progress indicators
- Display remaining cycles until cancellation allowed
- Show subscription tenure/loyalty status
- Calculate and display subscription value earned

**Response Format:**

Returns a single integer representing the current cycle number:
```json
3
```

**Response Examples:**

**New subscription (just created):**
```json
1
```

**After 5 successful billing attempts:**
```json
6
```
Note: Initial order (1) + 5 successful renewals = Cycle 6

**Important Considerations:**

**Cycle vs. Billing Attempts:**
- Failed billing attempts don't increment cycle
- Skipped orders don't increment cycle
- Manual order creation may not increment cycle
- Cycle represents successful billing events only

**Paused Subscriptions:**
- Cycle number remains frozen while paused
- Resumes at same cycle when un-paused
- Pause duration doesn't affect cycle count

**Minimum/Maximum Cycles:**
- `minCycles`: Minimum cycles before cancellation allowed
- `maxCycles`: Subscription auto-expires after this many cycles
- Use this endpoint to check progress towards these limits

**Data Source:**
- Queries Appstle database (not Shopify API)
- Counts records in subscription_billing_attempt table
- Filters by SUCCESS status only
- Fast response time (< 100ms typically)

**Integration Example:**

**Check if customer can cancel:**
```javascript
// Get subscription details
const contract = await getSubscriptionContract(contractId);
const currentCycle = await fetch(
  `/api/external/v2/subscription-contract-details/current-cycle/${contractId}`,
  { headers: { 'X-API-Key': 'your-key' } }
).then(r => r.json());

const minCycles = contract.minCycles || 0;

if (currentCycle >= minCycles) {
  console.log('Customer can cancel now');
  showCancelButton();
} else {
  const cyclesRemaining = minCycles - currentCycle;
  console.log(`Must complete ${cyclesRemaining} more orders before canceling`);
  showMinimumCommitmentMessage(cyclesRemaining);
}
```

**Display progress to max cycles:**
```javascript
const currentCycle = await getCycleNumber(contractId);
const maxCycles = contract.maxCycles;

if (maxCycles) {
  const progress = (currentCycle / maxCycles) * 100;
  console.log(`Subscription ${progress.toFixed(0)}% complete (${currentCycle}/${maxCycles})`);
  
  if (currentCycle === maxCycles) {
    console.log('This is the final cycle - subscription will expire after this order');
  }
}
```

**Performance Characteristics:**

**Fast Query:**
- Simple database count query
- Indexed by shop and contractId
- Typical response time: 50-150ms
- Suitable for real-time UI updates

**Best Practices:**

1. **Cache Results**: Cache cycle number briefly (few minutes) to reduce API calls
2. **Combine with Contract Data**: Fetch contract details simultaneously for min/max cycles
3. **Handle Edge Cases**: Account for subscriptions with no successful billings yet
4. **Display Progress**: Show cycle number in customer-friendly format ("Order 3 of 12")
5. **Sync with Billing**: Update cycle number after each billing attempt completes

**Common Misunderstandings:**

**Myth: Cycle = Months Subscribed**
- Reality: Cycle = Successful billing attempts, not time elapsed
- A paused subscription stays at same cycle for months
- Failed payments don't advance the cycle

**Myth: First order is Cycle 0**
- Reality: Cycles start at 1, not 0
- Initial/origin order is Cycle 1

**Related Fields:**
- `minCycles`: Minimum cycles before cancellation (from contract)
- `maxCycles`: Maximum cycles before auto-expiry (from contract)
- `billingInterval`: Frequency between cycles (from contract)

**Authentication:** Requires valid X-API-Key header



## OpenAPI

````yaml /subscription/admin-api-swagger.json get /api/external/v2/subscription-contract-details/current-cycle/{contractId}
openapi: 3.0.1
info:
  description: >-
    Comprehensive API documentation for managing subscriptions, payments, and
    related operations. These APIs allow you to programmatically manage
    subscription lifecycles, handle payments, configure products, and integrate
    subscription functionality into your applications.
  title: Admin APIs
  version: 0.0.1
servers:
  - url: https://subscription-admin.appstle.com
security: []
tags:
  - description: >-
      Core APIs for managing the complete subscription lifecycle including
      creation, updates, pausing, resuming, and cancellation of subscriptions.
    name: Subscription Management
  - description: >-
      APIs for managing subscription payment methods, processing payments,
      handling payment retries, and updating billing information.
    name: Subscription Payments
  - description: >-
      APIs for managing subscription contracts including delivery schedules,
      pricing, order notes, billing cycles, and shipping addresses.
    name: Subscription Contracts
  - description: >-
      APIs for managing products within subscriptions including adding,
      removing, updating quantities, and swapping products.
    name: Subscription Products
  - description: >-
      APIs for handling billing operations, payment processing, and financial
      transactions related to subscriptions.
    name: Billing & Payments
  - description: >-
      APIs for managing discounts and promotional codes applied to
      subscriptions.
    name: Subscription Discounts
  - description: >-
      APIs for managing one-time add-on products that can be purchased alongside
      recurring subscription items.
    name: Subscription One-Time Products
  - description: >-
      APIs for managing subscription plans, pricing tiers, and plan
      configurations.
    name: Subscription Plans
  - description: >-
      APIs for managing customizable product boxes and bundles where customers
      can select multiple items.
    name: Build-a-Box & Bundles
  - description: >-
      APIs for managing the product catalog including product information,
      variants, and inventory.
    name: Product Catalog
  - description: >-
      APIs for managing operational settings, configurations, and administrative
      functions.
    name: Operations & Settings
  - description: >-
      APIs powering the customer-facing portal where subscribers can manage
      their own subscriptions.
    name: Customer Portal
  - description: APIs for managing customer information, profiles, and account details.
    name: Customers
  - description: >-
      APIs for retrieving aggregated subscription data, customer subscription
      history, and account-level subscription information.
    name: Subscription Data
  - description: >-
      APIs for managing delivery profiles, shipping rates, free shipping
      configuration, and delivery method options on subscriptions.
    name: Delivery & Shipping
  - description: >-
      APIs for managing storefront customization including custom CSS, theme
      settings, label translations, and merchant-defined widget configuration.
    name: Customization
  - description: >-
      APIs for configuring cancellation flows, retention offers, cancellation
      reason management, and win-back automation.
    name: Customer Retention
paths:
  /api/external/v2/subscription-contract-details/current-cycle/{contractId}:
    get:
      tags:
        - Subscription Management
        - Subscription Contracts
      summary: Get current billing cycle number for a subscription contract
      description: >-
        Retrieves the current billing cycle number for a specific subscription
        contract. The cycle number represents how many successful billing
        attempts have occurred for this subscription, starting from 1 for the
        initial order.


        **What is a Billing Cycle?**

        A billing cycle represents one completed billing period in a
        subscription's lifetime. Each successful billing attempt increments the
        cycle count. This number is crucial for:

        - Tracking subscription progress towards minimum/maximum cycle limits

        - Applying cycle-based pricing adjustments (discounts after N cycles)

        - Determining eligibility for cancellation (minimum cycles requirement)

        - Calculating customer lifetime value

        - Analyzing subscription retention metrics


        **How Cycle Counting Works:**


        **Initial Order:**

        - Cycle 1 starts when subscription is first created

        - Initial order counts as the first billing cycle

        - Includes origin order that created the subscription


        **Subsequent Orders:**

        - Each successful billing attempt increments cycle by 1

        - Only SUCCESS status billing attempts are counted

        - Failed/skipped billing attempts do NOT increment cycle

        - Paused subscriptions maintain their current cycle number


        **Calculation Formula:**

        ```

        Current Cycle = 1 + (Number of Successful Billing Attempts)

        ```


        **Example Timeline:**

        - Day 1: Subscription created, initial order → Cycle 1

        - Day 30: First recurring order successful → Cycle 2

        - Day 60: Second recurring order successful → Cycle 3

        - Day 90: Billing fails (payment declined) → Still Cycle 3

        - Day 95: Retry successful → Cycle 4


        **Use Cases:**


        **1. Cancellation Eligibility:**

        - Verify customer has met minimum cycle requirement

        - Enforce contract terms (e.g., "3 month minimum")

        - Display "Can cancel after N more orders" messaging

        - Block premature cancellations


        **2. Pricing Adjustments:**

        - Apply introductory pricing for first N cycles

        - Trigger loyalty discounts after X cycles

        - Calculate when pricing changes take effect

        - Implement "First 3 months 50% off" promotions


        **3. Customer Retention:**

        - Identify subscriptions at risky cycle counts

        - Send retention campaigns at specific milestones

        - Track average cycles before churn

        - Celebrate subscription anniversaries


        **4. Analytics & Reporting:**

        - Calculate customer lifetime value (cycle × price)

        - Analyze subscription duration distribution

        - Track retention curves by cohort

        - Measure success of lifecycle campaigns


        **5. Customer Portal Display:**

        - Show "Order #X of Y" progress indicators

        - Display remaining cycles until cancellation allowed

        - Show subscription tenure/loyalty status

        - Calculate and display subscription value earned


        **Response Format:**


        Returns a single integer representing the current cycle number:

        ```json

        3

        ```


        **Response Examples:**


        **New subscription (just created):**

        ```json

        1

        ```


        **After 5 successful billing attempts:**

        ```json

        6

        ```

        Note: Initial order (1) + 5 successful renewals = Cycle 6


        **Important Considerations:**


        **Cycle vs. Billing Attempts:**

        - Failed billing attempts don't increment cycle

        - Skipped orders don't increment cycle

        - Manual order creation may not increment cycle

        - Cycle represents successful billing events only


        **Paused Subscriptions:**

        - Cycle number remains frozen while paused

        - Resumes at same cycle when un-paused

        - Pause duration doesn't affect cycle count


        **Minimum/Maximum Cycles:**

        - `minCycles`: Minimum cycles before cancellation allowed

        - `maxCycles`: Subscription auto-expires after this many cycles

        - Use this endpoint to check progress towards these limits


        **Data Source:**

        - Queries Appstle database (not Shopify API)

        - Counts records in subscription_billing_attempt table

        - Filters by SUCCESS status only

        - Fast response time (< 100ms typically)


        **Integration Example:**


        **Check if customer can cancel:**

        ```javascript

        // Get subscription details

        const contract = await getSubscriptionContract(contractId);

        const currentCycle = await fetch(
          `/api/external/v2/subscription-contract-details/current-cycle/${contractId}`,
          { headers: { 'X-API-Key': 'your-key' } }
        ).then(r => r.json());


        const minCycles = contract.minCycles || 0;


        if (currentCycle >= minCycles) {
          console.log('Customer can cancel now');
          showCancelButton();
        } else {
          const cyclesRemaining = minCycles - currentCycle;
          console.log(`Must complete ${cyclesRemaining} more orders before canceling`);
          showMinimumCommitmentMessage(cyclesRemaining);
        }

        ```


        **Display progress to max cycles:**

        ```javascript

        const currentCycle = await getCycleNumber(contractId);

        const maxCycles = contract.maxCycles;


        if (maxCycles) {
          const progress = (currentCycle / maxCycles) * 100;
          console.log(`Subscription ${progress.toFixed(0)}% complete (${currentCycle}/${maxCycles})`);
          
          if (currentCycle === maxCycles) {
            console.log('This is the final cycle - subscription will expire after this order');
          }
        }

        ```


        **Performance Characteristics:**


        **Fast Query:**

        - Simple database count query

        - Indexed by shop and contractId

        - Typical response time: 50-150ms

        - Suitable for real-time UI updates


        **Best Practices:**


        1. **Cache Results**: Cache cycle number briefly (few minutes) to reduce
        API calls

        2. **Combine with Contract Data**: Fetch contract details simultaneously
        for min/max cycles

        3. **Handle Edge Cases**: Account for subscriptions with no successful
        billings yet

        4. **Display Progress**: Show cycle number in customer-friendly format
        ("Order 3 of 12")

        5. **Sync with Billing**: Update cycle number after each billing attempt
        completes


        **Common Misunderstandings:**


        **Myth: Cycle = Months Subscribed**

        - Reality: Cycle = Successful billing attempts, not time elapsed

        - A paused subscription stays at same cycle for months

        - Failed payments don't advance the cycle


        **Myth: First order is Cycle 0**

        - Reality: Cycles start at 1, not 0

        - Initial/origin order is Cycle 1


        **Related Fields:**

        - `minCycles`: Minimum cycles before cancellation (from contract)

        - `maxCycles`: Maximum cycles before auto-expiry (from contract)

        - `billingInterval`: Frequency between cycles (from contract)


        **Authentication:** Requires valid X-API-Key header
      operationId: getCurrentCycleOfSubscriptionContractV2
      parameters:
        - description: API Key for authentication
          example: sk_live_1234567890abcdef
          in: header
          name: X-API-Key
          required: true
          schema:
            type: string
        - in: path
          name: contractId
          required: true
          schema:
            format: int64
            type: integer
      responses:
        '200':
          content:
            application/json:
              examples:
                Established subscription:
                  description: >-
                    Subscription has had 5 successful billing renewals plus
                    initial order
                  value: 6
                New subscription:
                  description: Subscription just created, on first billing cycle
                  value: 1
              schema:
                format: int32
                type: integer
          description: Successfully retrieved current billing cycle number
        '400':
          content:
            application/json:
              example:
                detail: Contract ID must be a valid positive integer
                status: 400
                title: Invalid contract ID
                type: https://example.com/errors/bad-request
          description: Bad request - Invalid contract ID
        '401':
          content:
            application/json:
              example:
                detail: Valid X-API-Key header is required
                status: 401
                title: Authentication required
                type: https://example.com/errors/unauthorized
          description: Authentication required - Missing or invalid API key
        '403':
          content:
            application/json:
              example:
                detail: Subscription contract does not belong to your shop
                status: 403
                title: Access denied
                type: https://example.com/errors/forbidden
          description: Forbidden - Contract does not belong to authenticated shop
        '404':
          content:
            application/json:
              example:
                detail: No subscription contract found with ID 12345
                status: 404
                title: Contract not found
                type: https://example.com/errors/not-found
          description: Contract not found

````