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

# Create an add-on

> Create one credit pack without replacing other catalog items.

Create one credit pack without replacing other catalog items. An add-on is a one-time Stripe Checkout purchase that grants a fixed number of credits after payment. It can top up a customer who already has a plan.

## Set the pack value

Set `type` to `credit_pack`, `creditAmount` to a positive integer, and `priceCents` to a positive integer in USD cents. For example, `creditAmount: 50` and `priceCents: 500` sells 50 credits for \$5.00. The ID is a stable API identifier with letters, numbers, underscores, or hyphens (up to 100 characters); the name is a display label.

The response contains the created `item` and `changed: true`. Another active add-on with the same ID returns `409 already_exists`. Credit-pack prices are created for each hosted Checkout session rather than synced as recurring Stripe catalog prices.

## Sell a pack

Create or find the customer, then call [Attach a plan or add-on](https://docs.integrateledger.com/api-reference/billing/attach.md) with `addOnId` and open its `checkoutUrl`. The purchase remains `pending_checkout` until Stripe confirms a paid session. Ledger grants the Checkout's credit amount once and shows the purchase in the customer dashboard. Repeating the same attach request while Checkout is open returns the existing link; a different pack can return `409 purchase_pending`.

The price and credit amount are fixed for an open Checkout. [Update an add-on](https://docs.integrateledger.com/api-reference/add-ons/update.md) returns `409 purchase_pending` if you try to change either value while a purchase is pending. When Stripe's signed `checkout.session.expired` event reaches Ledger, the pending purchase is removed and the edit can be retried. A browser cancel redirect alone does not expire the Stripe session. [Archive an add-on](https://docs.integrateledger.com/api-reference/add-ons/archive.md) hides it from new purchases while keeping purchase history. See [Customers](https://docs.integrateledger.com/customers.md) for the complete top-up flow.


## OpenAPI

````yaml openapi.json POST /v1/add-ons
openapi: 3.1.0
info:
  title: Ledger API
  version: 0.1.0
servers:
  - url: https://api.integrateledger.com
    description: Hosted Ledger API
security: []
paths:
  /v1/add-ons:
    post:
      tags:
        - Add-ons
      summary: Create an add-on
      operationId: createAddOn
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateAddOnInput'
      responses:
        '201':
          description: AddOn created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AddOnMutation'
              example:
                item:
                  id: extra_credits
                  name: Extra credits
                  type: credit_pack
                  creditAmount: 50
                  priceCents: 500
                changed: true
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
        '401':
          description: Invalid Ledger API key
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
        '409':
          description: Item ID already exists or add-on Checkout is pending
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
      security:
        - ApiKey: []
      x-codeSamples:
        - lang: bash
          label: cURL
          source: |-
            curl --request POST 'https://api.integrateledger.com/v1/add-ons' \
              -H "Authorization: Bearer $LEDGER_API_KEY" \
              -H 'Content-Type: application/json' \
              --data '{"id":"extra_credits","name":"Extra credits","type":"credit_pack","creditAmount":50,"priceCents":500}'
        - lang: python
          label: Python SDK (source only)
          source: >-
            import os

            from ledger_sdk import Ledger


            ledger = Ledger(api_key=os.environ["LEDGER_API_KEY"])

            ledger.create_add_on(id="extra_credits", name="Extra credits",
            credit_amount=50, price_cents=500)
        - lang: typescript
          label: TypeScript SDK (source only)
          source: >-
            import { Ledger } from "@ledger/sdk";


            const ledger = new Ledger({ apiKey: process.env.LEDGER_API_KEY ?? ""
            });

            await ledger.createAddOn({ id: "extra_credits", name: "Extra
            credits", type: "credit_pack", creditAmount: 50, priceCents: 500 });
components:
  schemas:
    CreateAddOnInput:
      type: object
      properties:
        id:
          type: string
          minLength: 1
          maxLength: 100
          pattern: ^[a-zA-Z0-9_-]+$
        name:
          type: string
          minLength: 1
          maxLength: 120
        type:
          type: string
          enum:
            - credit_pack
        creditAmount:
          type: integer
          exclusiveMinimum: 0
          maximum: 2147483647
        priceCents:
          type: integer
          exclusiveMinimum: 0
          maximum: 2147483647
      required:
        - id
        - name
        - type
        - creditAmount
        - priceCents
      additionalProperties: false
    AddOnMutation:
      type: object
      properties:
        item:
          $ref: '#/components/schemas/AddOnItem'
        changed:
          type: boolean
      required:
        - item
        - changed
    AddOnItem:
      type: object
      properties:
        id:
          type: string
          minLength: 1
          maxLength: 100
          pattern: ^[a-zA-Z0-9_-]+$
        name:
          type: string
          minLength: 1
          maxLength: 120
        type:
          type: string
          enum:
            - credit_pack
        creditAmount:
          type: integer
          exclusiveMinimum: 0
          maximum: 2147483647
        priceCents:
          type: integer
          exclusiveMinimum: 0
          maximum: 2147483647
      required:
        - id
        - name
        - type
        - creditAmount
        - priceCents
      additionalProperties: false
  securitySchemes:
    ApiKey:
      type: http
      scheme: bearer

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.