`subscriptionContractCreate` mutation ignores `nextBillingDate` in billing cycles

Hi :waving_hand:

I think there may be a problem with the subscriptionContractCreate mutation and its handling of the nextBillingDate field.

Example scenario

My goal: create a monthly pay-per-delivery subscription contract that starts 10 days from today.

  • Today: 2025-08-17
  • Desired first billing: 2025-08-27

Here’s the mutation I run:

mutation SubscriptionContractCreate($input: SubscriptionContractCreateInput!) {
  subscriptionContractCreate(input: $input) {
    draft {
      id
    }
    userErrors {
      code
      field
      message
    }
  }
}
variables: {
  input: {
    customerId: "[REDACTED]",
    currencyCode: "EUR",
    nextBillingDate: "2025-08-27T07:00:00.000Z",
    contract: {
      status: "PAUSED",
      nextBillingDate: "2025-08-27T07:00:00.000Z",
      paymentMethodId: "[REDACTED]",
      billingPolicy: {
        interval: "MONTH",
        intervalCount: 1,
      },
      deliveryPolicy: {
        interval: "MONTH",
        intervalCount: 1,
      },
      deliveryMethod: {
        shipping: {
          address: {
            firstName: "Foo",
            lastName: "Bar",
            phone: "",
            address1: "Test address 1",
            address2: "Test address 2",
            city: "Vilnius",
            province: null,
            countryCode: "LT",
            zip: "12345"
          }
        }
      }
    },
  }
}

The subscription contract is created successfully:

subscriptionContract(id: "gid://shopify/SubscriptionContract/123456789") {
  "nextBillingDate": "2025-08-27T07:00:00Z",
  "createdAt": "2025-08-17T16:40:18Z",
}

The issue

When I query the billing cycles:

{
  subscriptionBillingCycles(
    contractId: "gid://shopify/SubscriptionContract/123456789"
    first: 100
    billingCyclesIndexRangeSelector: { startIndex: 1, endIndex: 100 }
    ) {
    nodes {
      billingAttemptExpectedDate
      cycleIndex
      cycleStartAt
      cycleEndAt
    }
  }
}

The result shows that billingAttemptExpectedDate ignores my nextBillingDate and instead uses createdAt as the baseline:

{
  "data": {
    "subscriptionBillingCycles": {
      "nodes": [
        {
          "billingAttemptExpectedDate": "2025-09-17T16:00:00Z",
          "cycleIndex": 1,
          "cycleStartAt": "2025-08-17T16:40:19Z",
          "cycleEndAt": "2025-09-17T16:00:00Z",
          "skipped": false,
          "status": "UNBILLED",
          "billingAttempts": {
            "nodes": []
          }
        },
        {
          "billingAttemptExpectedDate": "2025-10-17T16:00:00Z",
          "cycleIndex": 2,
          "cycleStartAt": "2025-09-17T16:00:01Z",
          "cycleEndAt": "2025-10-17T16:00:00Z",
          "skipped": false,
          "status": "UNBILLED",
          "billingAttempts": {
            "nodes": []
          }
        }
      ]
    }
  }
}
  1. Is this the intended behavior?
  2. How can I achieve the following schedule?
  • First order: 2025-08-27 (from nextBillingDate)
  • Second order (first renewal) is on 2025-09-27
  • Third order (second renewal) is on 2025-10-27
  • … and so on

Would really appreciate clarification on whether this is a bug or if I’m missing an extra step to align billing cycles with the provided nextBillingDate.

Can you try but remove the milliseconds from your timestamp.
Same format as now but with the time only as HH:MM:SSZ

Hey did that work for you?
I suggested removing the milliseconds due to the format suggested by GraphQL and I’ve seen removing the milliseconds help elsewhere