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

# ACP promotions and discount configuration

> ACP Promotion object specification — how to configure discount types, active periods, and product targeting rules for AI agent commerce.

# Promotions Management

ACP supports managing promotion data through the REST API. Promotions can only be submitted via the API; SFTP file upload is not supported.

## 5.1 Promotion Object

| Field           | Type          | Required | Description                    |
| --------------- | ------------- | -------- | ------------------------------ |
| `id`            | string        | Yes      | Unique promotion identifier    |
| `title`         | string        | Yes      | Promotion name                 |
| `description`   | string        | No       | Detailed promotion description |
| `status`        | enum          | Yes      | Promotion status               |
| `active_period` | DateTimeRange | No       | Active time range              |
| `benefits`      | Benefit\[]    | Yes      | List of discount types         |
| `applies_to`    | ProductTarget | No       | Applicable product scope       |
| `url`           | URI string    | No       | Promotion details page URL     |

### Promotion Status

| Status      | Description                    |
| ----------- | ------------------------------ |
| `draft`     | Draft, not yet active          |
| `scheduled` | Scheduled, awaiting activation |
| `active`    | Currently active               |
| `expired`   | Has expired                    |
| `disabled`  | Manually disabled              |

### Active Time Range

`active_period` uses the DateTimeRange type, containing `start_time` and `end_time` fields:

```json theme={null}
{
  "active_period": {
    "start_time": "2026-04-01T00:00:00Z",
    "end_time": "2026-04-30T23:59:59Z"
  }
}
```

### Product Targeting

`applies_to` uses the ProductTarget type to specify which products the promotion applies to:

```json theme={null}
{
  "applies_to": {
    "product_id": "prod_001",
    "variant_ids": ["var_001_black", "var_001_white"]
  }
}
```

If `variant_ids` is not specified, the promotion applies to all variants of that product.

## 5.2 Three Discount Types

### Fixed Amount Discount (AmountOffBenefit)

```json theme={null}
{
  "type": "amount_off",
  "amount_off": {
    "amount": 1000,
    "currency": "USD"
  }
}
```

Deducts a fixed amount. The example above represents a \$10.00 USD discount (amounts use minor units, i.e., cents).

### Percentage Discount (PercentOffBenefit)

```json theme={null}
{
  "type": "percent_off",
  "percent_off": 20
}
```

Deducts by percentage. The example above represents a 20% discount.

### Free Shipping (FreeShippingBenefit)

```json theme={null}
{
  "type": "free_shipping"
}
```

Waives shipping fees. No additional parameters required.

## 5.3 Complete Promotion Example

```json theme={null}
{
  "id": "promo_summer_2026",
  "title": "Summer Sale - 25% Off Electronics",
  "description": "All electronics 25% off during summer promotion",
  "status": "scheduled",
  "active_period": {
    "start_time": "2026-06-01T00:00:00Z",
    "end_time": "2026-08-31T23:59:59Z"
  },
  "benefits": [
    {
      "type": "percent_off",
      "percent_off": 25
    }
  ],
  "applies_to": {
    "product_id": "prod_electronics_bundle",
    "variant_ids": ["var_laptop_001", "var_tablet_001"]
  },
  "url": "https://store.example.com/summer-sale"
}
```

## 5.4 API Submission

Promotions are upserted via the PATCH endpoint:

```http theme={null}
PATCH /product_feeds/:feed_id/promotions
Content-Type: application/json
Authorization: Bearer api_key_123

{
  "promotions": [
    {
      "id": "promo_summer_2026",
      "title": "Summer Sale",
      "status": "active",
      "benefits": [
        {
          "type": "percent_off",
          "percent_off": 25
        }
      ]
    }
  ]
}
```

Matched by `id`: existing records are updated, non-existing records are created.

## 5.5 Discounts in Checkout Sessions

When an AI agent creates a Checkout Session, promotion discounts are communicated through the following fields.

### Discount Codes

```json theme={null}
{
  "codes": ["SUMMER25", "WELCOME10"]
}
```

The `codes` array contains discount codes provided by the user.

### Applied Discounts (AppliedDiscount)

| Field         | Type          | Description                                             |
| ------------- | ------------- | ------------------------------------------------------- |
| `id`          | string        | Discount identifier                                     |
| `code`        | string        | Discount code                                           |
| `coupon`      | Coupon        | Coupon details                                          |
| `amount`      | Price         | Discount amount                                         |
| `automatic`   | boolean       | Whether automatically applied                           |
| `start`       | datetime      | Start time                                              |
| `end`         | datetime      | End time                                                |
| `method`      | enum          | `each` (per-item discount) or `across` (total discount) |
| `priority`    | number        | Priority (lower number means higher priority)           |
| `allocations` | Allocation\[] | Breakdown allocated to each line item                   |

### Coupon Object

```json theme={null}
{
  "coupon": {
    "name": "Summer 25% Off",
    "percent_off": 25,
    "duration": "repeating",
    "max_redemptions": 1000,
    "times_redeemed": 342
  }
}
```

Coupons support either `percent_off` (percentage discount) or `amount_off` (fixed amount discount) modes.

### Rejected Discounts (RejectedDiscount)

If a discount code is invalid or not applicable, it appears in the `rejected` array:

```json theme={null}
{
  "rejected": [
    {
      "code": "EXPIRED_CODE",
      "reason": "Coupon has expired"
    }
  ]
}
```

### Complete Discount Structure Example

```json theme={null}
{
  "codes": ["SUMMER25"],
  "applied": [
    {
      "id": "disc_001",
      "code": "SUMMER25",
      "coupon": {
        "name": "Summer Sale",
        "percent_off": 25
      },
      "amount": {
        "amount": 2500,
        "currency": "USD"
      },
      "automatic": false,
      "method": "across",
      "priority": 1,
      "allocations": []
    }
  ],
  "rejected": []
}
```

## 5.6 Best Practices

| Practice                    | Description                                                  |
| --------------------------- | ------------------------------------------------------------ |
| Use stable promotion IDs    | Keep the ID unchanged when updating promotions               |
| Set explicit time ranges    | Avoid promotions remaining in active status indefinitely     |
| Update status promptly      | Mark expired promotions as `disabled` or `expired`           |
| Test discount calculations  | Verify that minor-unit amount calculations are correct       |
| Specify applicable products | Use `applies_to` to precisely control promotion scope        |
| Price consistency           | Promotion prices must match actual discounts on your website |

***

**Next chapter**: [Chapter 6: Data Quality Best Practices](/en/book-4/ch6-data-quality) — ID stability, URL conventions, prohibited content
