> ## 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.

# Remove Addon

> Removes addon services from your cart by addon identifier

## Overview

The Remove Addon endpoint allows customers to remove previously selected addon services from their cart. This endpoint handles removal of addons at any scope (cart, item, or group level) and automatically recalculates cart totals.

<Note>
  **Key Features:**

  * Remove addon selections by ID
  * Supports partial removal from specific items
  * Automatically recalculates pricing
  * Maintains other addon selections
</Note>

## 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="addon_id" type="string" required>
  The unique identifier of the addon to remove
</ParamField>

<ParamField body="deselected_line_item_id" type="string">
  For partial removal: specific line item ID to remove the addon from
</ParamField>

<ParamField body="deselected_child_id" type="string">
  For hierarchical addons: specific child addon ID to remove
</ParamField>

## Response

Returns the complete shopping cart with the addon removed and pricing recalculated.

### Key Response Updates:

<ResponseField name="addons.selections" type="array">
  Updated selections array with the specified addon removed
</ResponseField>

<ResponseField name="addon_total" type="object">
  Recalculated total cost of remaining addons
</ResponseField>

<ResponseField name="total" type="object">
  Updated cart total reflecting the removal
</ResponseField>

## Code Examples

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

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/addons/_remove', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-firmly-authorization': 'YOUR_TOKEN'
    },
    body: JSON.stringify({
      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/_remove',
      headers={
          'Content-Type': 'application/json',
          'x-firmly-authorization': 'YOUR_TOKEN'
      },
      json={
          'addon_id': 'shipping_protection'
      }
  )

  cart = response.json()
  ```

  ```php PHP theme={null}
  <?php
  $curl = curl_init();

  $data = [
      'addon_id' => 'shipping_protection'
  ];

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/addons/_remove",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_HTTPHEADER => [
      "Content-Type: application/json",
      "x-firmly-authorization: YOUR_TOKEN"
    ],
    CURLOPT_POSTFIELDS => json_encode($data)
  ]);

  $response = curl_exec($curl);
  curl_close($curl);

  $cart = json_decode($response, true);
  ?>
  ```
</CodeGroup>

## Removal Examples by Tier

### Remove Cart-Level Addon

Remove shipping protection from the entire order:

```json theme={null}
{
  "addon_id": "shipping_protection"
}
```

**Before removal:**

```json theme={null}
{
  "addons": {
    "selections": [
      {
        "addon_id": "shipping_protection",
        "price": { "value": 12.99 }
      }
    ]
  },
  "addon_total": { "value": 12.99 }
}
```

**After removal:**

```json theme={null}
{
  "addons": {
    "selections": []
  },
  "addon_total": { "value": 0.00 }
}
```

### Remove Item-Level Addon

Remove extended warranty from specific items:

```json theme={null}
{
  "addon_id": "extended_warranty"
}
```

<Note>
  When removing an item-level addon without specifying `deselected_line_item_id`, it's removed from **all** items for which it was selected. Use `deselected_line_item_id` to remove specific items only.
</Note>

### Remove Hierarchical Addon

Remove a parent addon with child selections:

```json theme={null}
{
  "addon_id": "furniture_installation"
}
```

This removes the parent addon and all its selected child addons (e.g., white glove service, assembly).

<ResponseExample>
  ```json theme={null}
  {
    "cart_id": "cart_01H2XVBR8C8JS5MQSFPJ8HF9SA",
    "platform_id": "shopify",
    "shop_id": "staging.luma.gift",
    "display_name": "Luma Store",
    "cart_status": "active",
    "line_items": [
      {
        "line_item_id": "item-1",
        "sku": "MH07-XS-Gray",
        "variant_id": "MH07-XS-Gray",
        "quantity": 1,
        "price": {
          "currency": "USD",
          "value": 54.00,
          "number": 5400,
          "symbol": "$"
        }
      }
    ],
    "shipments": [
      {
        "shipment_id": "shipment-1",
        "line_item_ids": ["item-1"],
        "fulfillment_type": {
          "id": "SHIP_TO_ADDRESS",
          "name": "Ship to Address"
        }
      }
    ],
    "addons": {
      "offers": [
        {
          "addon_id": "shipping_protection",
          "display": {
            "name": "Shipping Protection",
            "description": "Protect your order against damage or loss during shipping"
          },
          "scope": "CART",
          "price": {
            "currency": "USD",
            "value": 12.99,
            "number": 1299,
            "symbol": "$"
          }
        },
        {
          "addon_id": "extended_warranty",
          "display": {
            "name": "3-Year Extended Warranty",
            "description": "Comprehensive coverage for furniture protection"
          },
          "scope": "ITEM",
          "eligible_line_item_ids": ["item-1"],
          "price": {
            "currency": "USD",
            "value": 199.99,
            "number": 19999,
            "symbol": "$"
          }
        }
      ],
      "selections": []  // Empty after removal
    },
    "sub_total": {
      "currency": "USD",
      "value": 54.00,
      "number": 5400,
      "symbol": "$"
    },
    "addon_total": {
      "currency": "USD",
      "value": 0.00,
      "number": 0,
      "symbol": "$"
    },
    "total": {
      "currency": "USD",
      "value": 54.00,
      "number": 5400,
      "symbol": "$"
    },
    "schema_version": "2.0"
  }
  ```
</ResponseExample>

## Common Scenarios

<Tabs>
  <Tab title="Change Selection">
    To change from one addon to another (e.g., switching warranty types):

    ```javascript theme={null}
    // Step 1: Remove current warranty
    await removeAddon({ addon_id: "warranty_1year" });

    // Step 2: Add new warranty
    await addAddon({ 
      selections: [{
        addon_id: "warranty_3year",
        selected_line_item_ids: ["item-1"]
      }]
    });
    ```
  </Tab>

  <Tab title="Clear All Addons">
    To remove all addons from a cart:

    ```javascript theme={null}
    // Get current selections
    const cart = await getCart();
    const selections = cart.addons.selections;

    // Remove each addon
    for (const selection of selections) {
      await removeAddon({ addon_id: selection.addon_id });
    }
    ```
  </Tab>

  <Tab title="Remove Before Checkout">
    Remove optional addons before proceeding to payment:

    ```javascript theme={null}
    // Remove non-essential addons
    const optionalAddons = ["gift_wrap", "expedited_processing"];

    for (const addonId of optionalAddons) {
      if (hasAddon(cart, addonId)) {
        await removeAddon({ addon_id: addonId });
      }
    }
    ```
  </Tab>
</Tabs>

## Error Responses

<Accordion title="400 Bad Request">
  Invalid request format or missing addon\_id

  ```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 not found in current selections

  ```json theme={null}
  {
    "code": 422,
    "error": "ErrorUnprocessableEntity",
    "description": "Addon not found in cart selections"
  }
  ```
</Accordion>

## Important Considerations

<Warning>
  **Removal Behavior:**

  * Removing a parent addon also removes all child selections
  * Item-level addons are removed from ALL items unless `deselected_line_item_id` is specified
  * Use `deselected_line_item_id` to remove from specific items only
  * Required addons cannot be removed without consequences
</Warning>

### Impact on Cart State

When an addon is removed:

1. **Pricing Updates**
   * Addon cost removed from totals
   * Tax recalculated if applicable
   * Shipping costs may change (for delivery-related addons)
2. **Offer Availability**
   * Removed addon returns to offers array
   * May become available for re-selection
   * Eligibility rules still apply
3. **Related Addons**
   * Child addons are removed with parent
   * Dependent addons may become unavailable
   * Group constraints are re-evaluated

## UI Implementation Guide

<Note>
  **Best Practices for Remove Actions:**

  1. **Confirmation**: Consider showing a confirmation dialog for high-value addons
  2. **Visual Feedback**: Update UI immediately after removal
  3. **Price Display**: Show savings when addon is removed
  4. **Undo Option**: Consider offering a quick "undo" to re-add
  5. **Clear Messaging**: Explain what will be removed (especially for hierarchical addons)
</Note>

### Example UI Flow

```javascript theme={null}
async function handleRemoveAddon(addonId, addonName, price) {
  // Show confirmation for valuable addons
  if (price > 50) {
    const confirmed = await showConfirmDialog({
      title: `Remove ${addonName}?`,
      message: `This will remove $${price} from your order.`,
      confirmText: 'Remove',
      cancelText: 'Keep'
    });
    
    if (!confirmed) return;
  }
  
  // Remove addon
  try {
    showLoadingState();
    const updatedCart = await removeAddon({ addon_id: addonId });
    updateCartUI(updatedCart);
    showSuccessMessage(`${addonName} removed`);
  } catch (error) {
    showErrorMessage('Failed to remove addon');
  }
}
```

## Related Endpoints

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