# Contracts

Learn how to model negotiated sales agreements with dedicated contract billing.

Use contracts to model negotiated sales agreements that require custom pricing, defined service periods, and mid-deal seat changes while keeping your product catalog clean and avoiding complex [subscription schedules](https://docs.stripe.com/api/subscription_schedules.md).

> This feature is in private preview. You can request early access by filling in the form below.

### Get early access to billing contracts.

Enter your email to request access.

```bash
curl https://docs.stripe.com/preview/register \
  -X POST \
  -H "Content-Type: application/json" \
  -H "Referer: https://docs.stripe.com/billing/contracts" \
  -d '{"email": "EMAIL", "preview": "billing_contracts"}'
```

## Compare contracts and subscriptions

Contracts and [subscriptions](https://docs.stripe.com/api/subscriptions.md) support different billing models and can coexist on the same platform.

|  | Contracts | Subscriptions |
| --- | --- | --- |
| Optimized for | Flexibility, with different terms for each customer | Scale, with the same terms across many customers |
| Pricing | Negotiated rates through overrides on top of catalog pricing | Standard catalog pricing |
| Lifecycle | Defined start and end dates | Recurring with no end date unless canceled |
| Driven by | Sales-led negotiations | Customer self-service |

Contracts and subscriptions use the same [products](https://docs.stripe.com/api/products.md) and [prices](https://docs.stripe.com/api/prices.md). For example, you can reference a product priced at 50 USD per seat per month by both a subscription and a contract, with the contract applying negotiated pricing through overrides.

## Understand how contracts work

Contracts include these building blocks for mapping to a negotiated deal:

- **Pricing lines**: Products from your existing catalog included in the agreement, with quantities and service periods.
- **Pricing overrides**: Negotiated rates that differ from your standard catalog pricing (price override or percentage multiplier).
- **License quantity**: Seat or unit counts that you can change mid-contract period.
- **Billing settings**: Invoicing cycle and payment terms specific to the deal.
- **One-time fees**: Fixed charges billed outside the recurring cycle, such as a setup or implementation fee.

### Contracts lifecycle

Contracts move through four statuses:

| Status | Description |
| --- | --- |
| `draft` | Configuration. No billing occurs. |
| `active` | Billing in effect. Invoices generated. |
| `ended` | End date reached. The contract completed its term. |
| `canceled` | Contract canceled before its end date. |

### Create a contract

Create a contract in `draft` status to map your billing cycle to your negotiated sales agreement, then activate it when you’re ready to begin billing.

This example creates a contract with a pricing line that references an existing product in your catalog:

```curl
curl -X POST https://api.stripe.com/v2/billing/contracts \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-06-24.preview" \
  --json '{
    "currency": "usd",
    "contract_number": "C-2026-0001",
    "pricing_lines": [
        {
            "starts_at": {
                "type": "timestamp",
                "timestamp": "2026-07-01T00:00:00Z"
            },
            "ends_at": {
                "type": "timestamp",
                "timestamp": "2027-07-01T00:00:00Z"
            },
            "pricing": {
                "type": "price",
                "price_details": {
                    "price": "{{PRICE_ID}}",
                    "quantity_changes": [
                        {
                            "effective_at": {
                                "type": "timestamp",
                                "timestamp": "2026-07-01T00:00:00Z"
                            },
                            "set": "12"
                        }
                    ],
                    "pricing_overrides": [
                        {
                            "type": "overwrite_price",
                            "priority": 20,
                            "overwrite_price": {
                                "unit_amount": "100"
                            }
                        }
                    ]
                }
            }
        }
    ],
    "pricing_overrides": [],
    "metadata": {},
    "billing_settings": {
        "billing_profile_details": {
            "customer": "{{CUSTOMER_ID}}"
        },
        "collection_settings_details": {
            "collection_method": "send_invoice"
        },
        "bill_settings_details": {
            "invoice": {
                "time_until_due": {
                    "interval": "month",
                    "interval_count": 1
                }
            }
        }
    }
  }'
```

### Activate a contract

Activate a contract to finalize the draft and create the first invoice when applicable. After activation, the contract `status` changes to `active`.

```curl
curl -X POST https://api.stripe.com/v2/billing/contracts/{{BILLINGCONTRACTID_ID}}/activate \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-06-24.preview"
```

### Create a contract with one-time fees

Use [one-time fees](https://docs.stripe.com/api/v2/billing-contracts/contracts/create.md?api-version=2026-06-24.preview#v2_create_contracts-one_time_fees) to bill fixed charges that aren’t tied to the recurring billing cycle, such as setup fees, implementation charges, or one-off professional services. Each one-time fee references a product from your catalog and specifies when to bill.

You can include one-time fees when [creating a contract](https://docs.stripe.com/api/v2/billing-contracts/contracts/create.md?api-version=2026-06-24.preview):

```curl
curl -X POST https://api.stripe.com/v2/billing/contracts \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-06-24.preview" \
  --json '{
    "currency": "usd",
    "contract_number": "C-2026-0042",
    "pricing_lines": [
        {
            "starts_at": {
                "type": "timestamp",
                "timestamp": "2026-07-01T00:00:00Z"
            },
            "ends_at": {
                "type": "timestamp",
                "timestamp": "2027-07-01T00:00:00Z"
            },
            "pricing": {
                "type": "price",
                "price_details": {
                    "price": "{{PRICE_ID}}",
                    "quantity_changes": [
                        {
                            "effective_at": {
                                "type": "timestamp",
                                "timestamp": "2026-07-01T00:00:00Z"
                            },
                            "set": "5"
                        }
                    ]
                }
            }
        }
    ],
    "one_time_fees": [
        {
            "product": "{{PRODUCT_ID}}",
            "amount": {
                "value": "500.00",
                "currency": "usd"
            },
            "bill_at": {
                "type": "now"
            }
        }
    ],
    "billing_settings": {
        "billing_profile_details": {
            "customer": "{{CUSTOMER_ID}}"
        },
        "collection_settings_details": {
            "collection_method": "send_invoice"
        },
        "bill_settings_details": {
            "invoice": {
                "time_until_due": {
                    "interval": "month",
                    "interval_count": 1
                }
            }
        }
    }
  }'
```

Each one-time fee accepts the following parameters. For full details, see [Create a contract](https://docs.stripe.com/api/v2/billing-contracts/contracts/create.md?api-version=2026-06-24.preview#v2_create_contracts-one_time_fees).

| Parameter | Description |
| --- | --- |
| [product](https://docs.stripe.com/api/v2/billing-contracts/contracts/create.md?api-version=2026-06-24.preview#v2_create_contracts-one_time_fees-product) | The ID of the product for this fee. |
| [amount](https://docs.stripe.com/api/v2/billing-contracts/contracts/create.md?api-version=2026-06-24.preview#v2_create_contracts-one_time_fees-amount) | The amount to bill, with `value` and `currency`. |
| [bill_at](https://docs.stripe.com/api/v2/billing-contracts/contracts/create.md?api-version=2026-06-24.preview#v2_create_contracts-one_time_fees-bill_at) | When to bill this fee. Set `type` to `now` to bill immediately, or `timestamp` with a specific date. |
| [lookup_key](https://docs.stripe.com/api/v2/billing-contracts/contracts/create.md?api-version=2026-06-24.preview#v2_create_contracts-one_time_fees-lookup_key) | An optional user-provided key to identify this fee for later updates or removal. |

To schedule a one-time fee for a future date instead of billing immediately, set `bill_at.type` to `timestamp`:

```curl
curl -X POST https://api.stripe.com/v2/billing/contracts \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-06-24.preview" \
  --json '{
    "currency": "usd",
    "contract_number": "C-2026-0042",
    "one_time_fees": [
        {
            "product": "{{PRODUCT_ID}}",
            "amount": {
                "value": "1000.00",
                "currency": "usd"
            },
            "bill_at": {
                "type": "timestamp",
                "timestamp": "2026-10-01T00:00:00Z"
            },
            "lookup_key": "implementation_fee"
        }
    ]
  }'
```

### Manage one-time fees on an existing contract

After creating a contract, you can add, update, or remove one-time fees using the [update contract](https://docs.stripe.com/api/v2/billing-contracts/contracts/update.md?api-version=2026-06-24.preview) endpoint with [one_time_fee_actions](https://docs.stripe.com/api/v2/billing-contracts/contracts/update.md?api-version=2026-06-24.preview#v2_update_contracts-one_time_fee_actions).

To add a new one-time fee to an existing contract:

```curl
curl -X POST https://api.stripe.com/v2/billing/contracts/{{BILLINGCONTRACTID_ID}} \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-06-24.preview" \
  --json '{
    "one_time_fee_actions": [
        {
            "type": "add",
            "add": {
                "product": "{{PRODUCT_ID}}",
                "amount": {
                    "value": "250.00",
                    "currency": "usd"
                },
                "bill_at": {
                    "type": "now"
                }
            }
        }
    ]
  }'
```

To update an existing one-time fee (by ID or `lookup_key`):

```curl
curl -X POST https://api.stripe.com/v2/billing/contracts/{{BILLINGCONTRACTID_ID}} \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-06-24.preview" \
  --json '{
    "one_time_fee_actions": [
        {
            "type": "update",
            "update": {
                "lookup_key": "implementation_fee",
                "amount": {
                    "value": "1500.00",
                    "currency": "usd"
                }
            }
        }
    ]
  }'
```

To remove a one-time fee:

```curl
curl -X POST https://api.stripe.com/v2/billing/contracts/{{BILLINGCONTRACTID_ID}} \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-06-24.preview" \
  --json '{
    "one_time_fee_actions": [
        {
            "type": "remove",
            "remove": {
                "lookup_key": "implementation_fee"
            }
        }
    ]
  }'
```

You can’t update or remove a one-time fee that has already been billed on an active contract.

### Cancel a contract

Cancel a contract to end it before the scheduled end date. You can specify whether to generate credit prorations for unused time.

```curl
curl -X POST https://api.stripe.com/v2/billing/contracts/{{BILLINGCONTRACTID_ID}}/cancel \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-06-24.preview" \
  --json '{
    "proration_behavior": "none"
  }'
```

### List invoices for a contract

After activating a contract, Stripe generates [invoices](https://docs.stripe.com/api/invoices.md). Use the [`contract` parameter](https://docs.stripe.com/api/invoices/list.md#list_invoices-contract) to [retrieve all invoices](https://docs.stripe.com/api/invoices/list.md) associated with a specific contract.

```curl
curl -G https://api.stripe.com/v1/invoices \
  -u "<<YOUR_SECRET_KEY>>:" \
  -H "Stripe-Version: 2026-06-24.preview" \
  -d "contract={{BILLINGCONTRACTID_ID}}"
```

## Testing

Use [test clocks](https://docs.stripe.com/billing/testing/test-clocks.md) to test your contract setup and simulate the advancement of time. Inspect the invoices and event notifications that Stripe generates as time advances.

## Dashboard

View all your contracts in the Stripe Dashboard list view and on the contract detail page. You can’t create contracts in the Dashboard.

### Limitations

Contracts don’t support all subscription features. Notable exceptions include the following.

- **Trials**: Contracts don’t have a trial status. To model a trial period, use pricing overrides to reduce pricing.
- **Discounts**: Contracts don’t support coupons and discounts. To reduce pricing, use pricing overrides.
- **Charge automatically**: Contracts support only `collection_method=send_invoice`. Support for `collection_method=charge_automatically` isn’t available.
- **Metered prices**: Contracts only support licensed prices.
