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

# Shipping Rules

> Configure carrier-routing rules that suggest the right carrier and service for every order, and optionally auto-buy the label.

## What shipping rules do

A **shipping rule** tells Arcus which carrier and service to suggest when you rate-shop a
package. Rules match on the order's source channel, total weight, item count, destination,
and product category. The first matching rule's suggested service is surfaced as the
**Suggested** badge on every rate row, and (when configured) the label is purchased
automatically when you Pack with Arcus.

Shipping rules are managed in **Settings → Shipping → Shipping Rules**, or via the
API at `/v1/shipping-rules`.

## Rule conditions

Every condition is optional. When set, all conditions are combined with AND. A rule with no
conditions matches every package.

| Condition        | Field                                                                  | Behavior                                                                                 |
| ---------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| Source channel   | `sales_channel_id`                                                     | Matches orders from that sales channel. NULL = any channel.                              |
| Weight band      | `min_weight` / `max_weight`                                            | Inclusive bounds in pounds.                                                              |
| Item-count band  | `item_count_min` / `item_count_max`                                    | Inclusive bounds on the total item quantity in the package. NULL = no item-count filter. |
| Destination      | `destination_country` / `destination_state` / `destination_zip_prefix` | Match the ship-to country, state, or ZIP prefix.                                         |
| Product category | `product_category_id`                                                  | Matches when at least one item in the package belongs to that category.                  |

### Priority and the category override

Rules are evaluated in **priority** order (lower number runs first). When two rules have the
same priority, the older one (earliest `created_at`) wins.

A **category-scoped rule** (one with `product_category_id` set) always wins over a
non-category rule, even when the non-category rule has a higher priority. This is the
"any product in this category always ships by this carrier" pattern.

## The order header override

If the order itself carries an explicit shipping method (`default_shipping_method`), that
method **overrides every rule**. The sales rep's choice at order entry always wins over an
automated rule.

## Auto-buy and cost absorption

A rule can do more than suggest. Two per-rule behaviors:

* **`auto_buy`** -- when the rule matches and resolves to exactly one carrier service,
  Pack with Arcus purchases the label automatically. Ambiguous rules (multiple allowed
  services) never auto-buy.
* **`absorb_cost`** -- whether your business absorbs the carrier cost (`true`), charges it
  to the customer (`false`), or defers to the entity-wide default (`null`). When the cost is
  charged, a freight line is added to the order. When absorbed, the carrier cost posts to
  your Freight Out expense account and the customer is not billed.

The entity-wide defaults live in **Settings → Shipping → Shipping Rule Defaults**
(`default_absorb_shipping_cost` and `default_auto_buy`).

## Suggested rates in the API

The rate-shop response includes a `suggestion` block and tags each rate row:

```json theme={null}
{
  "suggestion": {
    "source": "rule",
    "rule_id": "9f3c...",
    "rule_name": "Phone-In / 1-3.5 lb / 1 item",
    "preferred_service_token": "usps_priority",
    "auto_buy": true,
    "absorb_cost": false
  },
  "rates": [
    {
      "service_token": "usps_priority",
      "amount": 9.45,
      "is_suggested": true,
      "suggested_priority": 1,
      "is_default": false
    },
    {
      "service_token": "usps_ground_advantage",
      "amount": 6.10,
      "is_suggested": false,
      "suggested_priority": null,
      "is_default": true
    }
  ]
}
```

* `is_suggested` -- the rate matches a service the rule suggested.
* `suggested_priority` -- 1..N rank within the suggestion (1 = primary).
* `is_default` -- the cheapest rate row.

`source` is `header_override` when the order's shipping method drove the suggestion, `rule`
when a shipping rule matched, or `none` when no rule matched.

## Creating a rule via the API

```bash theme={null}
curl -X POST https://api.arcuserp.com/v1/shipping-rules \
  -H "Authorization: Bearer $ARCUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Phone-In / 1-3.5 lb / 1 item",
    "priority": 20,
    "min_weight": 1,
    "max_weight": 3.5,
    "item_count_min": 1,
    "item_count_max": 1,
    "shipping_tokens": ["usps_priority"],
    "preferred_service_token": "usps_priority",
    "auto_buy": true
  }'
```

Requires the `settings:write` scope. Supply `Idempotency-Key` to make the create safely
retryable.
