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

# Multi Update

> Updates multiple plans on a customer in a single request. Currently supports cancel actions (immediately, end of cycle, or uncancel) across one or more subscriptions.

Use this endpoint to cancel or uncancel several plans atomically in one call — for example canceling a main plan together with its add-ons, or plans across multiple entities.

export const DynamicResponseExample = ({json, statusCode = "200"}) => {
  const toCamelCase = str => {
    return str.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
  };
  const convertKeysToCamelCase = obj => {
    if (Array.isArray(obj)) {
      return obj.map(item => convertKeysToCamelCase(item));
    }
    if (obj !== null && typeof obj === "object") {
      return Object.keys(obj).reduce((acc, key) => {
        const camelKey = toCamelCase(key);
        acc[camelKey] = convertKeysToCamelCase(obj[key]);
        return acc;
      }, {});
    }
    return obj;
  };
  const [isTypeScript, setIsTypeScript] = useState(() => {
    if (typeof window !== "undefined") {
      try {
        const lang = localStorage.getItem("code");
        return JSON.parse(lang) === "typescript";
      } catch {
        return true;
      }
    }
    return true;
  });
  useEffect(() => {
    const onMintlifyStorage = event => {
      if (event.detail?.key === "code") {
        try {
          const value = JSON.parse(event.detail.value);
          setIsTypeScript(value === "typescript");
        } catch {}
      }
    };
    const pollInterval = setInterval(() => {
      try {
        const lang = localStorage.getItem("code");
        const value = JSON.parse(lang);
        setIsTypeScript(value === "typescript");
      } catch {}
    }, 300);
    document.addEventListener("mintlify-localstorage", onMintlifyStorage);
    return () => {
      document.removeEventListener("mintlify-localstorage", onMintlifyStorage);
      clearInterval(pollInterval);
    };
  }, []);
  const camelCaseJson = useMemo(() => convertKeysToCamelCase(json), [json]);
  const snakeCaseString = JSON.stringify(json, null, 2);
  const camelCaseString = JSON.stringify(camelCaseJson, null, 2);
  return <ResponseExample>
			{isTypeScript ? <CodeBlock language="json" filename={statusCode}>
					{camelCaseString}
				</CodeBlock> : <CodeBlock language="json" filename={statusCode}>
					{snakeCaseString}
				</CodeBlock>}
		</ResponseExample>;
};

export const DynamicResponseField = ({children, name, ...props}) => {
  const convertToCamelCase = str => {
    if (typeof str !== "string") return str;
    return str.replace(/[_-](\w)/g, (_, c) => c.toUpperCase());
  };
  const [lang, setLang] = useState(() => {
    if (typeof window !== "undefined") {
      const stored = localStorage.getItem("code");
      return stored || '"typescript"';
    }
    return '"typescript"';
  });
  useEffect(() => {
    const onMintlifyStorage = event => {
      const key = event.detail?.key;
      if (key === "code") {
        setLang(event.detail.value);
      }
    };
    const pollInterval = setInterval(() => {
      const current = localStorage.getItem("code");
      if (current && current !== lang) {
        setLang(current);
      }
    }, 500);
    document.addEventListener("mintlify-localstorage", onMintlifyStorage);
    return () => {
      document.removeEventListener("mintlify-localstorage", onMintlifyStorage);
      clearInterval(pollInterval);
    };
  }, [lang]);
  const resolvedName = useMemo(() => {
    try {
      const value = JSON.parse(lang);
      const useCamelCase = value === "typescript";
      return useCamelCase ? convertToCamelCase(name) : name;
    } catch {
      return name;
    }
  }, [name, lang]);
  return <ResponseField name={resolvedName} {...props}>
			{children}
		</ResponseField>;
};

export const DynamicParamField = ({children, body, path, ...props}) => {
  const convertToCamelCase = str => {
    if (typeof str !== "string") return str;
    return str.replace(/[_-](\w)/g, (_, c) => c.toUpperCase());
  };
  const [lang, setLang] = useState(() => {
    if (typeof window !== "undefined") {
      const stored = localStorage.getItem("code");
      return stored || '"typescript"';
    }
    return '"typescript"';
  });
  useEffect(() => {
    const onMintlifyStorage = event => {
      const key = event.detail?.key;
      if (key === "code") {
        setLang(event.detail.value);
      }
    };
    const pollInterval = setInterval(() => {
      const current = localStorage.getItem("code");
      if (current && current !== lang) {
        setLang(current);
      }
    }, 500);
    document.addEventListener("mintlify-localstorage", onMintlifyStorage);
    return () => {
      document.removeEventListener("mintlify-localstorage", onMintlifyStorage);
      clearInterval(pollInterval);
    };
  }, [lang]);
  const resolvedBody = useMemo(() => {
    try {
      const value = JSON.parse(lang);
      const useCamelCase = value === "typescript";
      return useCamelCase ? convertToCamelCase(body) : body;
    } catch {
      return body;
    }
  }, [body, lang]);
  const resolvedPath = useMemo(() => {
    try {
      const value = JSON.parse(lang);
      const useCamelCase = value === "typescript";
      return useCamelCase ? convertToCamelCase(path) : path;
    } catch {
      return path;
    }
  }, [path, lang]);
  return <ParamField body={resolvedBody} path={resolvedPath} {...props}>
			{children}
		</ParamField>;
};

<Note>
  The multi update endpoint applies updates to multiple plans in a single,
  atomic request. It currently supports cancel actions. For updating a single
  plan (like changing quantities or customizing items), use
  [update](/api-reference/billing/billingUpdate) instead.
</Note>

### Common Use Cases

<CodeGroup>
  ```typescript Cancel a plan and its add-on theme={null}
  const response = await autumn.billing.multiUpdate({
      customerId: "cus_123",
      updates: [
          { planId: "pro_plan", cancelAction: "cancel_end_of_cycle" },
          { planId: "addon_seats", cancelAction: "cancel_end_of_cycle" },
      ],
  });
  ```
</CodeGroup>

### Body Parameters

<DynamicParamField body="customer_id" type="string" required>
  The ID of the customer to update plans for.
</DynamicParamField>

<DynamicParamField body="entity_id" type="string">
  The ID of the entity to update plans for. Individual updates can override this with their own entity\_id.
</DynamicParamField>

<DynamicParamField body="updates" type="object[]" required>
  The list of plan updates to apply to the customer.

  <Expandable title="properties">
    <DynamicParamField body="plan_id" type="string">
      The ID of the plan to update. Optional if subscription\_id is provided.
    </DynamicParamField>

    <DynamicParamField body="subscription_id" type="string">
      A unique ID to identify the subscription to update. Useful when a customer has multiple products with the same plan.
    </DynamicParamField>

    <DynamicParamField body="entity_id" type="string">
      The ID of the entity this update targets. Overrides the top-level entity\_id for this update.
    </DynamicParamField>

    <DynamicParamField body="cancel_action" type="'cancel_immediately' | 'cancel_end_of_cycle' | 'uncancel'" required>
      Action to perform for cancellation. 'cancel\_immediately' cancels now with prorated refund, 'cancel\_end\_of\_cycle' cancels at period end, 'uncancel' reverses a pending cancellation.
    </DynamicParamField>

    <DynamicParamField body="proration_behavior" type="'prorate_immediately' | 'none'">
      How to handle proration for this update. 'prorate\_immediately' charges/credits prorated amounts now, 'none' skips creating any charges.
    </DynamicParamField>
  </Expandable>
</DynamicParamField>

### Response

<DynamicResponseField name="customer_id" type="string">
  The ID of the customer.
</DynamicResponseField>

<DynamicResponseField name="entity_id" type="string">
  The ID of the entity, if the plan was attached to an entity.
</DynamicResponseField>

<DynamicResponseField name="invoice" type="object">
  Invoice details if an invoice was created. Only present when a charge was made.

  <Expandable title="properties">
    <DynamicResponseField name="status" type="string | null">
      The status of the invoice (e.g., 'paid', 'open', 'draft').
    </DynamicResponseField>

    <DynamicResponseField name="stripe_id" type="string">
      The Stripe invoice ID.
    </DynamicResponseField>

    <DynamicResponseField name="total" type="number">
      The total amount of the invoice in cents.
    </DynamicResponseField>

    <DynamicResponseField name="currency" type="string">
      The three-letter ISO currency code (e.g., 'usd').
    </DynamicResponseField>

    <DynamicResponseField name="hosted_invoice_url" type="string | null">
      URL to the hosted invoice page where the customer can view and pay the invoice.
    </DynamicResponseField>
  </Expandable>
</DynamicResponseField>

<DynamicResponseField name="payment_url" type="string | null">
  URL to redirect the customer to complete payment. Null if no payment action is required.
</DynamicResponseField>

<DynamicResponseField name="required_action" type="object">
  Details about any action required to complete the payment. Present when the payment could not be processed automatically.

  <Expandable title="properties">
    <DynamicResponseField name="code" type="'3ds_required' | 'payment_method_required' | 'payment_failed' | 'payment_processing'">
      The type of action required to complete the payment.
    </DynamicResponseField>

    <DynamicResponseField name="reason" type="string">
      A human-readable explanation of why this action is required.
    </DynamicResponseField>
  </Expandable>
</DynamicResponseField>

<ResponseExample>
  ```json 200 theme={null}
  {
    "customer_id": "cus_123",
    "invoice": {
      "status": "paid",
      "stripe_id": "in_1234",
      "total": -20,
      "currency": "usd",
      "hosted_invoice_url": "https://invoice.stripe.com/..."
    },
    "payment_url": null
  }
  ```
</ResponseExample>


## OpenAPI

````yaml openapi POST /v1/billing.multi_update
openapi: 3.1.0
info:
  title: Autumn API
  version: 2.3.0
servers:
  - url: https://api.useautumn.com
    description: Production server
security:
  - secretKey: []
paths:
  /v1/billing.multi_update:
    post:
      tags:
        - billing
      description: >-
        Updates multiple plans on a customer in a single request. Currently
        supports cancel actions (immediately, end of cycle, or uncancel) across
        one or more subscriptions.


        Use this endpoint to cancel or uncancel several plans atomically in one
        call — for example canceling a main plan together with its add-ons, or
        plans across multiple entities.
      operationId: multiUpdate
      parameters:
        - name: x-api-version
          in: header
          required: true
          schema:
            type: string
            default: 2.3.0
          x-speakeasy-globals-hidden: true
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                customer_id:
                  type: string
                  description: The ID of the customer to update plans for.
                entity_id:
                  type: string
                  description: >-
                    The ID of the entity to update plans for. Individual updates
                    can override this with their own entity_id.
                updates:
                  type: array
                  minItems: 1
                  items:
                    type: object
                    properties:
                      plan_id:
                        type: string
                        description: >-
                          The ID of the plan to update. Optional if
                          subscription_id is provided.
                      subscription_id:
                        type: string
                        description: >-
                          A unique ID to identify the subscription to update.
                          Useful when a customer has multiple products with the
                          same plan.
                      entity_id:
                        type: string
                        description: >-
                          The ID of the entity this update targets. Overrides
                          the top-level entity_id for this update.
                      cancel_action:
                        enum:
                          - cancel_immediately
                          - cancel_end_of_cycle
                          - uncancel
                        type: string
                        title: CancelAction
                        description: >-
                          Action to perform for cancellation.
                          'cancel_immediately' cancels now with prorated refund,
                          'cancel_end_of_cycle' cancels at period end,
                          'uncancel' reverses a pending cancellation.
                      proration_behavior:
                        enum:
                          - prorate_immediately
                          - none
                        type: string
                        description: >-
                          How to handle proration for this update.
                          'prorate_immediately' charges/credits prorated amounts
                          now, 'none' skips creating any charges.
                    required:
                      - cancel_action
                  description: The list of plan updates to apply to the customer.
              required:
                - customer_id
                - updates
              title: MultiUpdateParams
              examples:
                - customer_id: cus_123
                  updates:
                    - plan_id: pro_plan
                      cancel_action: cancel_end_of_cycle
                    - plan_id: addon_seats
                      cancel_action: cancel_end_of_cycle
            example:
              customer_id: cus_123
              updates:
                - plan_id: pro_plan
                  cancel_action: cancel_end_of_cycle
                - plan_id: addon_seats
                  cancel_action: cancel_end_of_cycle
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  customer_id:
                    type: string
                    description: The ID of the customer.
                  entity_id:
                    type: string
                    description: >-
                      The ID of the entity, if the plan was attached to an
                      entity.
                  invoice:
                    type: object
                    properties:
                      status:
                        anyOf:
                          - type: string
                          - type: 'null'
                        description: >-
                          The status of the invoice (e.g., 'paid', 'open',
                          'draft').
                      stripe_id:
                        type: string
                        description: The Stripe invoice ID.
                      total:
                        type: number
                        description: The total amount of the invoice in cents.
                      currency:
                        type: string
                        description: The three-letter ISO currency code (e.g., 'usd').
                      hosted_invoice_url:
                        anyOf:
                          - type: string
                          - type: 'null'
                        description: >-
                          URL to the hosted invoice page where the customer can
                          view and pay the invoice.
                    required:
                      - status
                      - stripe_id
                      - total
                      - currency
                      - hosted_invoice_url
                    description: >-
                      Invoice details if an invoice was created. Only present
                      when a charge was made.
                  payment_url:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: >-
                      URL to redirect the customer to complete payment. Null if
                      no payment action is required.
                  required_action:
                    type: object
                    properties:
                      code:
                        enum:
                          - 3ds_required
                          - payment_method_required
                          - payment_failed
                          - payment_processing
                        type: string
                        description: The type of action required to complete the payment.
                      reason:
                        type: string
                        description: >-
                          A human-readable explanation of why this action is
                          required.
                    required:
                      - code
                      - reason
                    description: >-
                      Details about any action required to complete the payment.
                      Present when the payment could not be processed
                      automatically.
                required:
                  - customer_id
                  - payment_url
                examples:
                  - customer_id: cus_123
                    invoice:
                      status: paid
                      stripe_id: in_1234
                      total: -20
                      currency: usd
                      hosted_invoice_url: https://invoice.stripe.com/...
                    payment_url: null
              example:
                customer_id: cus_123
                invoice:
                  status: paid
                  stripe_id: in_1234
                  total: -20
                  currency: usd
                  hosted_invoice_url: https://invoice.stripe.com/...
                payment_url: null
      x-codeSamples:
        - lang: typescript
          label: Typescript (SDK)
          source: |-
            import { Autumn } from 'autumn-js'

            const autumn = new Autumn()

            const result = await autumn.billing.multiUpdate({
              customerId: "cus_123",
              updates: [
                {
                  planId: "pro_plan",
                  cancelAction: "cancel_end_of_cycle",
                },
                {
                  planId: "addon_seats",
                  cancelAction: "cancel_end_of_cycle",
                },
              ],
            });
        - lang: python
          label: Python (SDK)
          source: |-
            from autumn_sdk import Autumn

            autumn = Autumn(secret_key="am_sk_test...")

            res = autumn.billing.multi_update(
                customer_id="cus_123",
                updates=[
                    {
                        "plan_id": "pro_plan",
                        "cancel_action": "cancel_end_of_cycle",
                    },
                    {
                        "plan_id": "addon_seats",
                        "cancel_action": "cancel_end_of_cycle",
                    },
                ],
            )
components:
  securitySchemes:
    secretKey:
      type: http
      scheme: bearer
      bearerFormat: JWT

````