> ## 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 valid subscription contract IDs for a customer

> Retrieves a set of all valid (active, paused, or otherwise non-deleted) subscription contract IDs for a specific customer. This endpoint returns only the contract IDs without detailed subscription information, making it ideal for quick lookups and validation checks.

**What Are Valid Subscription Contracts?**
Valid contracts are subscriptions that exist in the system and haven't been permanently deleted. This includes subscriptions in all states except those that have been hard-deleted or hidden from the system. The contract IDs returned represent subscriptions that can be queried, modified, or managed through other API endpoints.

**Contract States Included:**

**Active States:**
- `ACTIVE` - Currently active and billing recurring subscriptions
- `PAUSED` - Temporarily paused subscriptions (customer can resume)

**Inactive States:**
- `CANCELLED` - Cancelled subscriptions (retained for historical data)
- `EXPIRED` - Subscriptions that reached their max cycle limit
- `FAILED` - Subscriptions with payment failures (may be in dunning)

**Excluded:**
- Hard-deleted subscription records
- Hidden subscriptions (marked for cleanup)
- Subscriptions from test/development that were purged

**Use Cases:**

**1. Customer Portal:**
- Check if customer has any subscriptions before showing portal
- Display subscription count in dashboard
- Validate customer access to subscription management

**2. Integration & Automation:**
- Pre-flight check before bulk operations
- Verify customer has subscriptions before sending emails
- Filter customers for targeted campaigns (has active subscriptions)

**3. Validation & Security:**
- Verify a specific contract ID belongs to a customer
- Validate user permissions before showing subscription details
- Check authorization for subscription modification requests

**4. Analytics & Reporting:**
- Count total subscriptions per customer
- Identify customers with multiple subscriptions
- Build customer segmentation based on subscription count

**Response Format:**

Returns a `Set<Long>` containing Shopify subscription contract IDs.

```json
[123456789, 123456790, 123456791]
```

**Set Properties:**
- **Unique values**: No duplicate contract IDs
- **Unordered**: IDs are not in any specific order
- **Numeric**: IDs are Long integers (not GraphQL GIDs)

**Common Response Scenarios:**

**Customer with multiple subscriptions:**
```json
[5234567890, 5234567891, 5234567892, 5234567893]
```

**Customer with single subscription:**
```json
[5234567890]
```

**Customer with no subscriptions:**
```json
[]
```

**Integration Examples:**

**Example 1: Check if customer has subscriptions**
```javascript
const contractIds = await fetch('/api/external/v2/subscription-customers/valid/12345', {
  headers: { 'X-API-Key': 'your-api-key' }
}).then(r => r.json());

if (contractIds.length > 0) {
  console.log(`Customer has ${contractIds.length} subscriptions`);
  // Show customer portal
} else {
  console.log('Customer has no subscriptions');
  // Redirect to create subscription page
}
```

**Example 2: Validate contract ownership**
```javascript
const customerId = 12345;
const contractIdToVerify = 5234567890;

const validContracts = await fetch(`/api/external/v2/subscription-customers/valid/${customerId}`, {
  headers: { 'X-API-Key': 'your-api-key' }
}).then(r => r.json());

if (validContracts.includes(contractIdToVerify)) {
  console.log('Customer owns this contract - allowing access');
  // Proceed with subscription modification
} else {
  console.log('Unauthorized - contract does not belong to customer');
  // Return 403 Forbidden
}
```

**Performance Characteristics:**

**Fast Response:**
- Lightweight query (returns only IDs, not full subscription data)
- Typical response time: 50-200ms
- Suitable for real-time validation checks

**Scalability:**
- Efficient even for customers with 100+ subscriptions
- Database query uses indexed customer ID field
- Minimal network payload (just array of numbers)

**Important Notes:**

**Contract ID Format:**
- Returns numeric Shopify contract IDs (e.g., `5234567890`)
- NOT Shopify GraphQL GIDs (e.g., `gid://shopify/SubscriptionContract/...`)
- Use these IDs with other Appstle API endpoints

**Data Freshness:**
- Returns data from Appstle database (not real-time Shopify query)
- Data is updated via webhooks (typically < 1 second lag)
- If data seems stale, use sync endpoint to refresh

**Empty Response:**
- Empty array `[]` means customer has no valid subscriptions
- This is NOT an error - it's a valid response
- Returns 200 OK with empty array (not 404)

**Security & Authorization:**
- Customer ID is validated against authenticated shop
- Cannot query customers from other shops
- API key must have customer read permissions

**Best Practices:**

1. **Use for Validation**: Perfect for quick ownership/existence checks
2. **Cache Locally**: Cache results briefly to reduce API calls
3. **Check Empty Array**: Always handle empty array case gracefully
4. **Combine with Details**: Use this for initial check, then fetch full details if needed
5. **Avoid Polling**: Don't poll this endpoint repeatedly - use webhooks for updates

**When to Use vs. Other Endpoints:**

**Use this endpoint when you:**
- Need just the contract IDs (not full subscription details)
- Want to validate a customer has subscriptions
- Need to verify contract ownership for authorization
- Want fast, lightweight responses

**Use subscription-customers-detail endpoint when you:**
- Need full subscription details (status, products, billing dates, etc.)
- Want to display subscription information to users
- Need to make decisions based on subscription state

**Related Endpoints:**
- `GET /api/external/v2/subscription-customers-detail/valid/{customerId}` - Get full subscription details
- `GET /api/external/v2/subscription-contract-details` - Query subscriptions with filters
- `GET /api/external/v2/subscription-contracts/contract-external/{contractId}` - Get single contract details

**Authentication:** Requires valid X-API-Key header or api_key parameter (deprecated)



## OpenAPI

````yaml /subscription/admin-api-swagger.json get /api/external/v2/subscription-customers/valid/{customerId}
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-customers/valid/{customerId}:
    get:
      tags:
        - Customers
        - Subscription Contracts
      summary: Get valid subscription contract IDs for a customer
      description: >-
        Retrieves a set of all valid (active, paused, or otherwise non-deleted)
        subscription contract IDs for a specific customer. This endpoint returns
        only the contract IDs without detailed subscription information, making
        it ideal for quick lookups and validation checks.


        **What Are Valid Subscription Contracts?**

        Valid contracts are subscriptions that exist in the system and haven't
        been permanently deleted. This includes subscriptions in all states
        except those that have been hard-deleted or hidden from the system. The
        contract IDs returned represent subscriptions that can be queried,
        modified, or managed through other API endpoints.


        **Contract States Included:**


        **Active States:**

        - `ACTIVE` - Currently active and billing recurring subscriptions

        - `PAUSED` - Temporarily paused subscriptions (customer can resume)


        **Inactive States:**

        - `CANCELLED` - Cancelled subscriptions (retained for historical data)

        - `EXPIRED` - Subscriptions that reached their max cycle limit

        - `FAILED` - Subscriptions with payment failures (may be in dunning)


        **Excluded:**

        - Hard-deleted subscription records

        - Hidden subscriptions (marked for cleanup)

        - Subscriptions from test/development that were purged


        **Use Cases:**


        **1. Customer Portal:**

        - Check if customer has any subscriptions before showing portal

        - Display subscription count in dashboard

        - Validate customer access to subscription management


        **2. Integration & Automation:**

        - Pre-flight check before bulk operations

        - Verify customer has subscriptions before sending emails

        - Filter customers for targeted campaigns (has active subscriptions)


        **3. Validation & Security:**

        - Verify a specific contract ID belongs to a customer

        - Validate user permissions before showing subscription details

        - Check authorization for subscription modification requests


        **4. Analytics & Reporting:**

        - Count total subscriptions per customer

        - Identify customers with multiple subscriptions

        - Build customer segmentation based on subscription count


        **Response Format:**


        Returns a `Set<Long>` containing Shopify subscription contract IDs.


        ```json

        [123456789, 123456790, 123456791]

        ```


        **Set Properties:**

        - **Unique values**: No duplicate contract IDs

        - **Unordered**: IDs are not in any specific order

        - **Numeric**: IDs are Long integers (not GraphQL GIDs)


        **Common Response Scenarios:**


        **Customer with multiple subscriptions:**

        ```json

        [5234567890, 5234567891, 5234567892, 5234567893]

        ```


        **Customer with single subscription:**

        ```json

        [5234567890]

        ```


        **Customer with no subscriptions:**

        ```json

        []

        ```


        **Integration Examples:**


        **Example 1: Check if customer has subscriptions**

        ```javascript

        const contractIds = await
        fetch('/api/external/v2/subscription-customers/valid/12345', {
          headers: { 'X-API-Key': 'your-api-key' }
        }).then(r => r.json());


        if (contractIds.length > 0) {
          console.log(`Customer has ${contractIds.length} subscriptions`);
          // Show customer portal
        } else {
          console.log('Customer has no subscriptions');
          // Redirect to create subscription page
        }

        ```


        **Example 2: Validate contract ownership**

        ```javascript

        const customerId = 12345;

        const contractIdToVerify = 5234567890;


        const validContracts = await
        fetch(`/api/external/v2/subscription-customers/valid/${customerId}`, {
          headers: { 'X-API-Key': 'your-api-key' }
        }).then(r => r.json());


        if (validContracts.includes(contractIdToVerify)) {
          console.log('Customer owns this contract - allowing access');
          // Proceed with subscription modification
        } else {
          console.log('Unauthorized - contract does not belong to customer');
          // Return 403 Forbidden
        }

        ```


        **Performance Characteristics:**


        **Fast Response:**

        - Lightweight query (returns only IDs, not full subscription data)

        - Typical response time: 50-200ms

        - Suitable for real-time validation checks


        **Scalability:**

        - Efficient even for customers with 100+ subscriptions

        - Database query uses indexed customer ID field

        - Minimal network payload (just array of numbers)


        **Important Notes:**


        **Contract ID Format:**

        - Returns numeric Shopify contract IDs (e.g., `5234567890`)

        - NOT Shopify GraphQL GIDs (e.g.,
        `gid://shopify/SubscriptionContract/...`)

        - Use these IDs with other Appstle API endpoints


        **Data Freshness:**

        - Returns data from Appstle database (not real-time Shopify query)

        - Data is updated via webhooks (typically < 1 second lag)

        - If data seems stale, use sync endpoint to refresh


        **Empty Response:**

        - Empty array `[]` means customer has no valid subscriptions

        - This is NOT an error - it's a valid response

        - Returns 200 OK with empty array (not 404)


        **Security & Authorization:**

        - Customer ID is validated against authenticated shop

        - Cannot query customers from other shops

        - API key must have customer read permissions


        **Best Practices:**


        1. **Use for Validation**: Perfect for quick ownership/existence checks

        2. **Cache Locally**: Cache results briefly to reduce API calls

        3. **Check Empty Array**: Always handle empty array case gracefully

        4. **Combine with Details**: Use this for initial check, then fetch full
        details if needed

        5. **Avoid Polling**: Don't poll this endpoint repeatedly - use webhooks
        for updates


        **When to Use vs. Other Endpoints:**


        **Use this endpoint when you:**

        - Need just the contract IDs (not full subscription details)

        - Want to validate a customer has subscriptions

        - Need to verify contract ownership for authorization

        - Want fast, lightweight responses


        **Use subscription-customers-detail endpoint when you:**

        - Need full subscription details (status, products, billing dates, etc.)

        - Want to display subscription information to users

        - Need to make decisions based on subscription state


        **Related Endpoints:**

        - `GET
        /api/external/v2/subscription-customers-detail/valid/{customerId}` - Get
        full subscription details

        - `GET /api/external/v2/subscription-contract-details` - Query
        subscriptions with filters

        - `GET
        /api/external/v2/subscription-contracts/contract-external/{contractId}`
        - Get single contract details


        **Authentication:** Requires valid X-API-Key header or api_key parameter
        (deprecated)
      operationId: getValidSubscriptionCustomerV2
      parameters:
        - description: Id
          in: path
          name: customerId
          required: true
          schema:
            format: int64
            type: integer
        - description: API Key (Deprecated - Use Header X-API-Key instead)
          in: query
          name: api_key
          required: false
          schema:
            type: string
        - in: header
          name: X-API-Key
          required: false
          schema:
            type: string
      responses:
        '200':
          content:
            application/json:
              examples:
                Customer with multiple subscriptions:
                  description: Customer with multiple subscriptions
                  value:
                    - 5234567890
                    - 5234567891
                    - 5234567892
                    - 5234567893
                Customer with no subscriptions:
                  description: Customer with no subscriptions
                  value: []
                Customer with single subscription:
                  description: Customer with single subscription
                  value:
                    - 5234567890
              schema:
                items:
                  format: int64
                  type: integer
                type: array
          description: >-
            Successfully retrieved valid subscription contract IDs. Returns a
            set of contract IDs (may be empty if customer has no subscriptions).
        '400':
          content:
            application/json:
              example:
                detail: Customer ID must be a valid positive integer
                status: 400
                title: Invalid customer ID
                type: https://example.com/errors/bad-request
          description: Bad request - Invalid customer ID format
        '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: Customer 12345 does not belong to your shop
                status: 403
                title: Access denied
                type: https://example.com/errors/forbidden
          description: Forbidden - Customer does not belong to authenticated shop
        '429':
          content:
            application/json:
              example:
                detail: Too many requests. Please retry after 60 seconds.
                retryAfter: 60
                status: 429
                title: Rate limit exceeded
                type: https://example.com/errors/rate-limit
          description: Rate limit exceeded

````