Tags & Routing

What are tags?

Tags are short string labels attached to cart line items. When a rate request reaches the ShipRateAPI API, the tags on every item are pooled into a single basket-level set and matched against the tag rules on each rate table — for example, restricting a rate table to baskets containing cold-storage items, or excluding a rate table entirely when anything tagged hazmat is present.

Tags are evaluated per basket, not per item. The rating engine flattens the tags from every line item into one pool and evaluates each rate table once against that pool. A single hazmat item therefore excludes a table for the whole basket, and a single cold-storageitem satisfies that table's required tags for the whole basket — including the untagged items sitting alongside it. There is no per-item rating: one basket, one decision per table.

How tags are set — per platform
PlatformMethod
Magento 2Layer 1: shiprate_tags product attribute (comma-separated)
Layer 2: Admin attribute mapping rules — map any EAV attribute value to a tag
ShopifyLine item property named shiprate_tags (comma-separated), set when the item is added to the cart.
The native Shopify product Tags field is not read by the connector.
BigCommerceNot available. BigCommerce does not expose product tags in its rate callback, so the connector always sends an empty tag array.
commercetoolsProduct attribute named shiprate_tags (comma-separated) — read per line item by the connector
Custom / RESTPass tags directly in the items[].tags array of the API payload
BigCommerce: because every BigCommerce request arrives with no tags, any rate table with requiredTags set will never match a BigCommerce basket — those tables are silently skipped and their rates never appear at checkout. Keep at least one table with no required tags for BigCommerce zones, and use order value or weight guards instead of tags to route BigCommerce traffic.
Magento 2 — attribute mapping rules

The attribute mapping table (under Stores → Configuration → Sales → Delivery Methods → ShipRateAPI Live Rates → Attribute Tag Mapping) lets you derive tags from existing product attributes without touching each product. This is useful when you already have structured data in attributes such as hazmat_class, temperature_zone, or product_category_code.

Example rules:

Attribute CodeOperatorValueTag applied
temperature_zoneequalschilledcold-storage
hazmat_classnot equals(empty)dangerous-goods
namecontainsglassfragile

Attribute codes are validated against the Magento EAV catalog when you save the config. Rules with an invalid attribute code are rejected with a descriptive error before the config is persisted. At runtime, if an attribute cannot be read (e.g. it was deleted after the config was saved), the rule is skipped with a warning logged — the checkout flow is not interrupted.

Tags in the API payload

Tags appear in the items[].tags array. Every connector filters out empty strings, and the API trims and lowercases each inbound tag on arrival. Deduplication is Magento-only — the Magento module merges its two tag layers and removes duplicates; the Shopify and commercetools connectors send whatever remains once empties are dropped. Duplicates are harmless either way, since matching is a membership test — though they still count toward the 20-tag limit below. A product with no tags sends an empty array.

"items": [
  {
    "sku":    "CHILLED-001",
    "name":   "Organic Milk 2L",
    "qty":    1,
    "price":  1.80,
    "weight": 2.1,
    "tags":   ["cold-storage", "perishable"]
  },
  {
    "sku":    "STANDARD-002",
    "name":   "Reusable Bag",
    "qty":    2,
    "price":  0.99,
    "weight": 0.05,
    "tags":   []
  }
]
How tags route a basket to a rate table

Every rate table carries three tag fields: requiredTags, excludedTags, and matchMode. The rating engine checks them against the basket tag pool in a fixed order, before any weight, order value, or bracket logic runs.

  1. Excluded tags are evaluated first, and win outright. If any tag in excludedTags appears anywhere in the basket, the table is skipped immediately with the reason tag_mismatchrequiredTags is never even read. An exclusion cannot be overridden by a required tag on the same table.
  2. Required tags are evaluated second, honouring matchMode. any — the default — needs at least one required tag present in the basket; all needs every required tag present. If the basket does not satisfy them, the table is skipped with tag_mismatch.
  3. A table with neither field set matches every basket — including baskets with no tags at all. That is what makes a table an unrestricted fallback.

Worked examples:

Table tag configBasket tagsOutcome
(none set)anything, including noneMatches — unrestricted fallback
required cold-storage, mode anycold-storageMatches
required cold-storage, medicine, mode anymedicineMatches — any needs just one
required cold-storage, medicine, mode allmedicineSkipped — all needs both present
excluded hazmatfragile, hazmatSkipped — one hazmat item excludes the whole basket
required cold-storage, excluded hazmatcold-storage, hazmatSkipped — exclusion is checked first and wins
Limits and normalisation. A line item may carry at most 20 tags, and a basket at most 500 items — exceeding either is a validation error, not a silent truncation. Inbound tags are trimmed, lowercased, and stripped of empties by the API, and matching is case-insensitive, so Cold-Storage and cold-storage are the same tag.
Configuring routing rules in the portal

Tags are not configured as standalone rules — they are fields on a rate table. Once tags are flowing in the API payload, open Rate Tables in the admin portal sidebar, then edit (or create) the table you want to restrict. Its form carries three tag fields: Required tags, Tag match mode (shown once at least one required tag is set), and Excluded tags.

Because tags live on the table itself, they combine naturally with that table's zone, carrier, schedule window, and order value guards — a basket must satisfy all of them for the table to produce a rate. Setting the same tag as both required and excluded on one table makes it impossible to match; the Coverage Scanner flags that as an error, along with zones that have no unrestricted fallback table.