# Add or remove product on a contract

Use this workflow to add or remove an add-on product, also referred to as a sub product, on an existing Contract.

This is handled by updating the Contract with one or more commands. The command determines whether a product should be added or removed.

## Endpoint

```http
POST /v1/cm/contract/{contract-guid}
```

Where `{contract-guid}` is the ID of the Contract.

## When to use

Use this workflow when an existing Contract should be updated with an additional product or when an existing add-on product should be removed.

Typical use cases include:

- adding an add-on product to an active or pending contract
- removing an add-on product from a contract
- ending an add-on product from a specific date
- adding product-specific price values
- applying product changes triggered from an external CRM, self-service solution, or partner system

## Request structure

The request contains a `RequestId` and a list of `Commands`.

Each command contains:

| Field | Description |
|---|---|
| `CommandName` | The name of the command to execute, for example `AddProduct` or `RemoveProduct`. |
| `CommandData` | The command-specific payload. |

```json
{
  "RequestId": "30c0bead-f68b-4203-85e4-09322c5aa616",
  "Commands": [
    {
      "CommandName": "AddProduct",
      "CommandData": {}
    }
  ]
}
```

## Add product

Use `AddProduct` to add an add-on product to an existing Contract.

```json
{
  "RequestId": "30c0bead-f68b-4203-85e4-09322c5aa616",
  "Commands": [
    {
      "CommandName": "AddProduct",
      "CommandData": {
        "ProductId": "766b176d2b4b4cbaae1a0ae5260154c8",
        "ProductName": "Kundespesifikk prod spot",
        "StartDate": "2025-06-18",
        "InteractivePrices": [
          {
            "Name": "i:Paaslag",
            "Value": "SA12000"
          }
        ],
        "EndDate": "",
        "Comment": ""
      }
    }
  ]
}
```

### AddProduct fields

| Field | Description |
|---|---|
| `ProductId` | Identifier of the product to add. |
| `ProductName` | Name of the product. |
| `StartDate` | Date from which the product should apply. |
| `InteractivePrices` | Product-specific price values. Required when the product has interactive fields. |
| `EndDate` | Optional end date for the product. Leave empty if the product should continue without a known end date. |
| `Comment` | Optional comment for the product change. |

Products used on contracts must already exist in UtilityCloud.

Some products have interactive fields. When a product has interactive fields, the `InteractivePrices` array must include name-value pairs for the required fields. Values should be specified in the primary currency unit, using period (`.`) as decimal separator when decimal values are used.

## Remove product

Use `RemoveProduct` to remove an add-on product from a Contract.

```json
{
  "RequestId": "f20ae19b-06a5-4bf6-93b5-956e6ac843ae",
  "Commands": [
    {
      "CommandName": "RemoveProduct",
      "CommandData": {
        "ProductId": "766b176d2b4b4cbaae1a0ae5260154c8",
        "EndDate": "2025-06-11",
        "Index": 2
      }
    }
  ]
}
```

### RemoveProduct fields

| Field | Description |
|---|---|
| `ProductId` | Identifier of the product to remove. |
| `EndDate` | Date from which the product should no longer apply. |
| `Index` | Index of the product in the Contract product list. |

The `Index` property is needed because a Contract can contain the same add-on product in different time periods.

## Response

A valid request returns:

```http
202 Accepted
```

The operation is accepted for processing. Depending on the product, Service Type, contract status, and tenant configuration, the change may affect settlement, billing, contract history, and emitted events.

## Notes

A Contract can contain one primary product and optional add-on products.

The API examples may refer to add-on products as `sub products`.

Use a new `RequestId` for each update request. The request id is used for tracing and duplicate request handling.

When adding a product, verify that the product exists and that any required interactive price values are included.

When removing a product, include `Index` if the same product can appear more than once on the Contract.

## Related endpoints

```http
GET /v1/cm/contract/{guid}
POST /v1/cm/contract/{contract-guid}
POST /v1/pm/products
```