--- title: "Attach" openapi: "openapi POST /v1/billing.attach" --- import { DynamicParamField } from "/components/dynamic-param-field.jsx"; import { DynamicResponseField } from "/components/dynamic-response-field.jsx"; import { DynamicResponseExample } from "/components/dynamic-response-example.jsx"; The attach endpoint subscribes a customer to a plan. It handles new subscriptions, upgrades, and downgrades automatically. For modifying an existing subscription (like changing quantities or canceling), use [update](/api-reference/billing/billingUpdate) instead. ### Common Use Cases ```typescript Subscribe to a plan const response = await autumn.billing.attach({ customerId: "cus_123", planId: "pro_plan", }); if (response.paymentUrl) { // Redirect customer to checkout window.location.href = response.paymentUrl; } ``` ```typescript Custom pricing const response = await autumn.billing.attach({ customerId: "cus_123", planId: "enterprise_plan", customize: { price: { amount: 999, // $999 interval: "month", }, }, }); ``` ```typescript Attach plan with prepaid quantities const response = await autumn.billing.attach({ customerId: "cus_123", planId: "team_plan", featureQuantities: [{ featureId: "seats", quantity: 5 }], }); ``` ```typescript Pass metadata to Stripe subscription const response = await autumn.billing.attach({ customerId: "cus_123", planId: "pro_plan", checkoutSessionParams: { subscriptionData: { metadata: { userId: "internal-user-id", source: "upgrade-flow", }, }, }, }); ``` ### Stripe checkout session params Use `checkoutSessionParams` to pass additional data to the Stripe checkout session. Values you provide are deep-merged with Autumn's internal parameters, so your fields are preserved alongside ones Autumn sets automatically (like `trial_end` or internal metadata). This is useful for attaching custom metadata to the Stripe subscription created during checkout — for example, linking subscriptions to internal user IDs or tracking the source of the purchase.