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

# Add Addon

> Applies addon services to your cart

## Overview

The Add Addon endpoint enables customers to select value-added services offered by the merchant. Addons can apply at different scopes:

<CardGroup cols={3}>
  <Card title="Cart-Level" icon="shopping-cart">
    Applies to entire order (e.g., shipping protection)
  </Card>

  <Card title="Item-Level" icon="box">
    Applies to specific items (e.g., protection plans)
  </Card>

  <Card title="Group-Level" icon="folder">
    Applies to item groups (e.g., service bundles)
  </Card>
</CardGroup>

## Authentication

<Card>
  <ParamField header="x-firmly-authorization" type="string" required>
    Device authentication token to identify and map the session
  </ParamField>
</Card>

## Path Parameters

<ParamField path="domain" type="string" required>
  Domain of the merchant website (e.g., `staging.luma.gift`)
</ParamField>

## Request Body

<ParamField body="selections" type="array" required>
  Array containing a single addon selection. Only one addon should be modified per request to map to UI events like checkbox or radio button clicks.

  **Selection Object Properties:**

  * `addon_id` (string, required): Unique identifier for the addon to select
  * `selected_line_item_ids` (array, optional): For item-level addons: array of line item IDs to apply the addon to
  * `selected_child_ids` (array, optional): For hierarchical addons: array of child addon IDs to include
</ParamField>

## Response

Returns the complete shopping cart with updated addon selections and recalculated pricing.

### Key Response Fields:

<ResponseField name="addons.offers" type="array">
  All available addon options based on cart contents
</ResponseField>

<ResponseField name="addons.selections" type="array">
  Currently selected addons with pricing details
</ResponseField>

<ResponseField name="addon_total" type="object">
  Total cost of all selected addons
</ResponseField>

<ResponseField name="schema_version" type="string">
  API schema version
</ResponseField>

## Code Examples by Tier

### Cart-Level Addon (Shipping Protection)

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/addons \
    --header 'Content-Type: application/json' \
    --header 'x-firmly-authorization: YOUR_TOKEN' \
    --data '{
      "selections": [
        {
          "addon_id": "shipping_protection"
        }
      ]
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/addons', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-firmly-authorization': 'YOUR_TOKEN'
    },
    body: JSON.stringify({
      selections: [
        {
          addon_id: 'shipping_protection'
        }
      ]
    })
  });

  const cart = await response.json();
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/addons',
      headers={
          'Content-Type': 'application/json',
          'x-firmly-authorization': 'YOUR_TOKEN'
      },
      json={
          'selections': [
              {
                  'addon_id': 'shipping_protection'
              }
          ]
      }
  )

  cart = response.json()
  ```
</CodeGroup>

### Item-Level Addon (Extended Warranty)

Apply extended warranty to specific items with per-item pricing:

```json theme={null}
{
  "selections": [
    {
      "addon_id": "extended_warranty",
      "selected_line_item_ids": ["item-1", "item-2"]
    }
  ]
}
```

### Group-Level Addon

Apply service to a predefined group of items:

```json theme={null}
{
  "selections": [
    {
      "addon_id": "remove-mattress123",
      "selected_line_item_ids": ["item-1", "item-2"]
    }
  ]
}
```

### Hierarchical Addon (Protection Plans)

Select a parent addon with child options:

```json theme={null}
{
  "selections": [
    {
      "addon_id": "protection-sofa-001",
      "selected_line_item_ids": ["item-1"],
      "selected_child_ids": ["FPP-3YR"]
    }
  ]
}
```

## Advanced Examples

### Adding Multiple Addons

To add multiple addons to a cart, make separate API calls for each addon:

```javascript theme={null}
// Add shipping protection
await addAddon({
  selections: [{
    addon_id: "shipping_protection"
  }]
});

// Add extended warranty
await addAddon({
  selections: [{
    addon_id: "extended_warranty",
    selected_line_item_ids: ["item-1", "item-2"]
  }]
});

// Add gift wrapping
await addAddon({
  selections: [{
    addon_id: "gift_wrap",
    selected_line_item_ids: ["item-3"]
  }]
});
```

<Note>
  Each addon selection requires a separate API call. This design maps to individual UI events like checkbox or radio button clicks, ensuring proper tracking and state management.
</Note>

### Complex Addon Selection

Some addons support hierarchical selections with child options:

```json theme={null}
{
  "selections": [
    {
      "addon_id": "personalization",
      "selected_line_item_ids": ["item-1"],
      "selected_child_ids": ["engraving_option"]
    }
  ]
}
```

<ResponseExample>
  ```json theme={null}
  {
    "cart_id": "cart-12345",
    "platform_id": "shopify",
    "shop_id": "staging.luma.gift",
    "display_name": "Luma Store",
    "cart_status": "active",
    "line_items": [
      {
        "line_item_id": "item-1",
        "variant_id": "MH07-XS-Gray",
        "quantity": 1,
        "price": {
          "currency": "USD",
          "value": 54.00,
          "number": 5400,
          "symbol": "$"
        }
      },
      {
        "line_item_id": "item-2",
        "variant_id": "WS12-XS-Orange",
        "quantity": 1,
        "price": {
          "currency": "USD",
          "value": 22.00,
          "number": 2200,
          "symbol": "$"
        }
      }
    ],
    "shipments": [
      {
        "shipment_id": "shipment-1",
        "line_item_ids": ["item-1", "item-2"],
        "fulfillment_type": {
          "id": "SHIP_TO_ADDRESS",
          "name": "Ship to Address"
        }
      }
    ],
    "addons": {
      "offers": [
        {
          "addon_id": "shipping_protection",
          "display": {
            "name": "Shipping Protection",
            "description": "Protect your entire order against shipping damage"
          },
          "scope": "CART",
          "coverage_mode": "PREDEFINED_GROUP",
          "price": {
            "currency": "USD",
            "value": 4.99,
            "number": 499,
            "symbol": "$"
          }
        },
        {
          "addon_id": "extended_warranty",
          "display": {
            "name": "Extended Warranty - 3 Year",
            "description": "Comprehensive coverage beyond manufacturer warranty"
          },
          "scope": "ITEM",
          "coverage_mode": "PER_ITEM",
          "eligible_line_item_ids": ["item-1", "item-2"],
          "line_item_pricing": {
            "item-1": {
              "price": {
                "currency": "USD",
                "value": 5.40,
                "number": 540,
                "symbol": "$"
              }
            },
            "item-2": {
              "price": {
                "currency": "USD",
                "value": 2.20,
                "number": 220,
                "symbol": "$"
              }
            }
          }
        }
      ],
      "selections": [
        {
          "addon_id": "shipping_protection",
          "price": {
            "currency": "USD",
            "value": 4.99,
            "number": 499,
            "symbol": "$"
          }
        }
      ]
    },
    "sub_total": {
      "currency": "USD",
      "value": 76.00,
      "number": 7600,
      "symbol": "$"
    },
    "addon_total": {
      "currency": "USD",
      "value": 4.99,
      "number": 499,
      "symbol": "$"
    },
    "total": {
      "currency": "USD",
      "value": 80.99,
      "number": 8099,
      "symbol": "$"
    },
    "schema_version": "2.0"
  }
  ```
</ResponseExample>

## Understanding Addon Pricing

<Tabs>
  <Tab title="Cart-Level">
    **Single price for entire order**

    ```json theme={null}
    {
      "addon_id": "shipping_protection",
      "scope": "CART",
      "price": { "value": 4.99 }  // One price for whole cart
    }
    ```
  </Tab>

  <Tab title="Group-Level">
    **Price for item group**

    ```json theme={null}
    {
      "addon_id": "group_service",
      "scope": "GROUP",
      "price": { "value": 49.99 }  // Applied to group
    }
    ```
  </Tab>

  <Tab title="Item-Level">
    **Price varies by item**

    ```json theme={null}
    {
      "addon_id": "extended_warranty",
      "scope": "ITEM",
      "line_item_pricing": {
        "item-1": { "price": { "value": 5.40 } },  // Hero Hoodie warranty
        "item-2": { "price": { "value": 2.20 } }   // Radiant Tee warranty
      }
    }
    ```
  </Tab>
</Tabs>

## Error Responses

<Accordion title="400 Bad Request">
  Invalid request format or missing required parameters

  ```json theme={null}
  {
    "code": 400,
    "error": "ErrorInvalidInputBody",
    "description": "Request body validation failed"
  }
  ```
</Accordion>

<Accordion title="404 Not Found">
  Cart does not exist

  ```json theme={null}
  {
    "code": 404,
    "error": "ErrorCartNotFound",
    "description": "Cart not found for this domain"
  }
  ```
</Accordion>

<Accordion title="422 Unprocessable Entity">
  Addon constraints violated

  ```json theme={null}
  {
    "code": 422,
    "error": "ErrorUnprocessableEntity",
    "description": "Addon not eligible for selected items"
  }
  ```
</Accordion>

## Addon Eligibility Rules

<Note>
  **Addons are offered based on merchant rules:**

  * Item eligibility and categories
  * Business logic and thresholds
  * Merchant configuration
  * Product-specific requirements
</Note>

### Common Constraints

<CardGroup cols={2}>
  <Card title="Required Addons">
    Some addons must be selected before checkout

    ```json theme={null}
    {
      "required": true,
      "message": "Please select a delivery option"
    }
    ```
  </Card>

  <Card title="Exclusive Selection">
    Only one addon from a group can be selected

    ```json theme={null}
    {
      "selection_group": "warranty_options",
      "multiple": false
    }
    ```
  </Card>
</CardGroup>

## Best Practices

<Warning>
  **Implementation Tips:**

  1. Always check `eligible_line_item_ids` before applying addons
  2. Make one API call per addon selection (don't batch multiple addons)
  3. For hierarchical addons, select appropriate child IDs
  4. Handle group addons by including all related line items
  5. Update UI immediately after each addon selection
  6. Show clear pricing breakdown for transparency
  7. For radio button groups, remove the previous selection before adding the new one
</Warning>

## Related Endpoints

* [Remove Addon](/api-reference/addon-management/remove-addon) - Remove addon selections
* [Get Cart](/api-reference/cart-management/get-cart) - View current addon state
* [Overview](/api-reference/addon-management/overview) - Learn about the addon system
