Duties

Manage destination duty thresholds and rates by country of origin and HS code.

Duty rules belong to market countries. Reads require read_markets; writes require write_markets. Rules can be configured while duties are disabled. Each country has at most one rule. Its de minimis value is an exact decimal in the currency assigned to that country in Pricing. Default and HS-code rates preserve one of three explicit shapes: ad_valorem uses rate, specific uses amount plus per, and compound uses all three. Irrelevant fields are rejected, not ignored. HS codes accept dotted, spaced, or hyphenated display forms but are stored canonically as an even 2-12 digit code; canonical collisions fail the write. Update is partial. Use clear_de_minimis_value to remove the threshold and default_duty_rate_delete_origin to remove an origin’s default rate. Sending hs_rates replaces the complete map; do not combine it with an HS-rate upsert or delete. The de minimis comparison uses imported merchandise after discounts, excluding domestic goods. Values equal to the threshold are not exempt.

Endpoints#

Get duty limits

GET read_markets

Read the limits used by duty-rule screens and integrations.

Returns the live rule, HS-rate, search, and pagination limits enforced by the service. Read this before building create or edit forms instead of hardcoding values.

Path parameters

Name Type Description
marketId required uuid

Market id.

Example: 9a1f2c3d-4e5f-6789-abcd-ef0123456789

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    marketId must be a valid UUID.

  • 404 MARKET_NOT_FOUND

    The market does not exist in this store.

List available duty countries

GET read_markets

Find the market countries that can receive a duty rule.

Returns a paginated list of the market's countries, whether duties are enabled for each country, and whether a rule already exists. The readiness counts identify shippable catalog items missing weight, HS code, or country of origin.

Path parameters

Name Type Description
marketId required uuid

Market id.

Example: 9a1f2c3d-4e5f-6789-abcd-ef0123456789

Query parameters

Name Type Description
search string

Search by localized country name or ISO country code.

Example: india
page integer

Page number, starting at 1.

Example: 1
per_page integer

Rows per page, capped by the live duty limits.

Example: 20

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    marketId must be a valid UUID.

  • 404 MARKET_NOT_FOUND

    The market does not exist in this store.

  • 400 MARKET_DUTY_SEARCH_TOO_LONG

    The search value exceeds the live duty limit.

  • 400 VALIDATION_LIST_INVALID_PAGE

    Page is not an integer of at least 1.

  • 400 VALIDATION_LIST_INVALID_LIMIT

    Per-page is outside the configured range.

List duty rules

GET read_markets

List the market's country duty rules.

Returns paginated rules with their de minimis value, origin-aware default rates, HS-code rates, status, and timestamps. Use the detail endpoint before editing a rule.

Path parameters

Name Type Description
marketId required uuid

Market id.

Example: 9a1f2c3d-4e5f-6789-abcd-ef0123456789

Query parameters

Name Type Description
search string

Search by localized country name or ISO country code.

Example: india
page integer

Page number, starting at 1.

Example: 1
per_page integer

Rows per page, capped by the live duty limits.

Example: 20

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    marketId must be a valid UUID.

  • 404 MARKET_NOT_FOUND

    The market does not exist in this store.

  • 400 MARKET_DUTY_SEARCH_TOO_LONG

    The search value exceeds the live duty limit.

  • 400 VALIDATION_LIST_INVALID_PAGE

    Page is not an integer of at least 1.

  • 400 VALIDATION_LIST_INVALID_LIMIT

    Per-page is outside the configured range.

Create a duty rule

POST write_markets

Add a duty rule for one country in the market.

The country must belong to the market, have a serving currency, and not already have a rule. Create an inactive rule while configuring rates; enable it once the required catalog data is ready. Default and HS-code rates may vary by origin country; use * as the fallback origin. Duty is charged on each line's customs value: its value after discounts, without the tax its price includes. In a tax-inclusive market, a line of 120 including 20% VAT at a 12% duty rate pays 12.00 duty, not 14.40. When the market's duty_collection_mode is collect_at_checkout, import VAT is charged on the goods plus their duty: 100 with 12 duty at 20% VAT is 22.40. Duty is calculated first; the VAT on duty uses each item's own tax rates, is always added on top of the duty (never included in a price), and is part of the order's tax total, so in a tax-inclusive market the total is prices plus duty plus VAT on duty. A successful create publishes duty_rules/create with the complete saved rule.

Path parameters

Name Type Description
marketId required uuid

Market id.

Example: 9a1f2c3d-4e5f-6789-abcd-ef0123456789

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
country_code required string

ISO 3166-1 alpha-2 destination country assigned to this market.

Example: IN
de_minimis_value decimal-string|null

Non-negative threshold for the customs value of imported merchandise (after discounts, without the tax prices include), in the currency assigned to this country. Domestic goods are excluded. Duty is not charged when that value is at or below the threshold. Precision follows the currency (zero decimals for JPY/KRW, three for KWD); maximum 99999999.9999. Send a decimal point without grouping or currency symbols.

Example: 1000.00
default_duty_rates object

Origin-country to duty-rate map. Use * for the fallback origin. Percentages allow 0-999.99 with up to two decimals; specific/compound amounts are non-negative per-unit or per-kg tariff coefficients with up to four decimals, maximum 999999999999999.9999. These coefficients may be smaller than a currency minor unit. Calculated duties are finalized once at currency precision and line allocations reconcile to the total.

Example: {"*":{"type":"ad_valorem","rate":"10"},"CN":{"type":"compound","rate":"5","amount":"20","per":"unit"}}
hs_rates object

Origin-country to canonical-HS-code duty-rate map. Display punctuation is accepted and normalized.

Example: {"*":{"8517":{"type":"ad_valorem","rate":"15"}}}
is_enabled required boolean

Whether this rule participates in duty calculation.

Example: true

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    marketId must be a valid UUID.

  • 404 MARKET_NOT_FOUND

    The market does not exist in this store.

  • 400 MARKET_DUTY_RULE_RATE_REQUIRED

    An enabled destination needs at least one rate.

  • 400 MARKET_DUTY_AMOUNT_INVALID

    The tariff amount is not a valid decimal.

  • 400 MARKET_DUTY_AMOUNT_NEGATIVE

    The tariff amount is negative.

  • 400 MARKET_DUTY_AMOUNT_TOO_LARGE

    The tariff amount exceeds 999999999999999.9999.

  • 400 MARKET_DUTY_AMOUNT_TOO_PRECISE

    The tariff coefficient exceeds four decimal places.

  • 400 MARKET_DUTY_RATE_INVALID

    The rate or update mutation combination is invalid.

  • 400 MARKET_DUTY_RATE_TOO_PRECISE

    The percentage exceeds two decimal places.

  • 400 MARKET_DUTY_DE_MINIMIS_INVALID

    The de minimis value is not a valid decimal.

  • 400 MARKET_DUTY_DE_MINIMIS_NEGATIVE

    The de minimis value is negative.

  • 400 MARKET_DUTY_DE_MINIMIS_TOO_LARGE

    The de minimis value exceeds the live maximum.

  • 400 MARKET_DUTY_DE_MINIMIS_TOO_PRECISE

    The de minimis value has too many decimal places.

  • 400 MARKET_DUTY_RATE_TYPE_INVALID

    A rate type is not ad_valorem, specific, or compound.

  • 400 MARKET_DUTY_RATE_SHAPE_INVALID

    A rate includes fields that do not belong to its selected type.

  • 400 MARKET_DUTY_RATE_REQUIRED

    An ad valorem or compound rate is missing its percentage.

  • 400 MARKET_DUTY_RATE_OUT_OF_RANGE

    A percentage rate is outside the supported range.

  • 400 MARKET_DUTY_AMOUNT_REQUIRED

    A specific or compound rate is missing its amount.

  • 400 MARKET_DUTY_RATE_PER_INVALID

    A specific or compound rate does not use kg or unit.

  • 400 MARKET_DUTY_HS_CODE_INVALID_FORMAT

    An HS code cannot be normalized to an even 2 to 12 digit code.

  • 400 MARKET_DUTY_HS_RATES_TOO_MANY

    The rule exceeds the live HS-rate limit.

  • 400 MARKET_DUTY_ORIGIN_INVALID

    An origin is invalid, matches the destination, or duplicates another origin after normalization.

  • 400 MARKET_DUTY_COUNTRY_NOT_IN_MARKET

    The destination country is not assigned to this market.

  • 409 MARKET_DUTY_RULE_ALREADY_EXISTS

    This country already has a duty rule in the market.

  • 400 MARKET_DUTY_RULE_LIMIT_REACHED

    The market has reached its live duty-rule limit.

  • 400 MARKET_DUTY_COUNTRY_CURRENCY_MISSING

    The destination country has no serving currency in this market.

Get a duty rule by country

GET read_markets

Read the complete duty rule for one destination country.

Use this endpoint when the destination country is known but the rule id is not. It returns the same complete object as the id-based detail endpoint.

Path parameters

Name Type Description
marketId required uuid

Market id.

Example: 9a1f2c3d-4e5f-6789-abcd-ef0123456789
countryCode required string

ISO 3166-1 alpha-2 destination country code.

Example: IN

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    marketId must be a valid UUID.

  • 404 MARKET_NOT_FOUND

    The market does not exist in this store.

  • 404 DUTY_RULE_COUNTRY_NOT_FOUND

    No duty rule exists for this destination.

Get a duty rule

GET read_markets

Read one duty rule and its complete rate configuration.

Use the returned rule to populate an edit form. HS codes are returned in canonical even-length 2 to 12 digit form, grouped by origin country.

Path parameters

Name Type Description
marketId required uuid

Market id.

Example: 9a1f2c3d-4e5f-6789-abcd-ef0123456789
ruleId required uuid

Duty country rule id.

Example: 7c9e4f2b-1a3d-4e5f-8b6c-2d0e1f3a4b5c

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    marketId must be a valid UUID.

  • 404 MARKET_NOT_FOUND

    The market does not exist in this store.

  • 404 DUTY_RULE_NOT_FOUND

    The duty rule does not exist in this market.

Update a duty rule

PUT write_markets

Change selected parts of one duty rule.

This is a partial update. Use explicit delete fields to remove de minimis, a default origin rate, or one HS-code rate. Sending hs_rates replaces the complete origin-to-HS map. An unchanged request publishes nothing; a successful change publishes duty_rules/update with the complete saved rule.

Path parameters

Name Type Description
marketId required uuid

Market id.

Example: 9a1f2c3d-4e5f-6789-abcd-ef0123456789
ruleId required uuid

Duty country rule id.

Example: 7c9e4f2b-1a3d-4e5f-8b6c-2d0e1f3a4b5c

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
de_minimis_value decimal-string|null

Set a non-negative threshold in the saved destination currency, at that currency precision and no greater than 99999999.9999.

Example: 1500.00
clear_de_minimis_value boolean

Remove the saved de minimis threshold. Omit de_minimis_value when this is true.

Example: true
default_duty_rate_upsert object

Add or replace one origin-specific default rate: origin_country_code plus rate.

Example: {"origin_country_code":"*","rate":{"type":"ad_valorem","rate":"12"}}
default_duty_rate_delete_origin string

Remove the default rate for this origin code. Use * for the fallback.

Example: CN
default_duty_rates object

Replace the complete origin-rate map in one transaction. Use * for the fallback origin.

Example: {"*":{"type":"ad_valorem","rate":"10"},"CN":{"type":"compound","rate":"5","amount":"20","per":"unit"}}
hs_rates object

Replace the complete origin-to-HS-code rate map. Do not combine this with an HS-rate upsert or delete.

Example: {"*":{"8517":{"type":"ad_valorem","rate":"15"}}}
hs_rate_upsert object

Add or replace one HS rate: origin code, HS code, and rate.

Example: {"origin_country_code":"*","code":"8517.13","rate":{"type":"specific","amount":"25","per":"unit"}}
hs_rate_delete_code string

Canonical or display-form HS code to remove.

Example: 8517.13
hs_rate_delete_origin string

Origin map from which hs_rate_delete_code is removed.

Example: *
is_enabled boolean

Whether this rule participates in duty calculation.

Example: true

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    marketId must be a valid UUID.

  • 404 MARKET_NOT_FOUND

    The market does not exist in this store.

  • 404 DUTY_RULE_NOT_FOUND

    The duty rule does not exist in this market.

  • 400 MARKET_DUTY_RULE_RATE_REQUIRED

    An enabled destination needs at least one rate.

  • 400 MARKET_DUTY_AMOUNT_INVALID

    The tariff amount is not a valid decimal.

  • 400 MARKET_DUTY_AMOUNT_NEGATIVE

    The tariff amount is negative.

  • 400 MARKET_DUTY_AMOUNT_TOO_LARGE

    The tariff amount exceeds 999999999999999.9999.

  • 400 MARKET_DUTY_AMOUNT_TOO_PRECISE

    The tariff coefficient exceeds four decimal places.

  • 400 MARKET_DUTY_RATE_INVALID

    The rate or update mutation combination is invalid.

  • 400 MARKET_DUTY_RATE_TOO_PRECISE

    The percentage exceeds two decimal places.

  • 400 MARKET_DUTY_DE_MINIMIS_INVALID

    The de minimis value is not a valid decimal.

  • 400 MARKET_DUTY_DE_MINIMIS_NEGATIVE

    The de minimis value is negative.

  • 400 MARKET_DUTY_DE_MINIMIS_TOO_LARGE

    The de minimis value exceeds the live maximum.

  • 400 MARKET_DUTY_DE_MINIMIS_TOO_PRECISE

    The de minimis value has too many decimal places.

  • 400 MARKET_DUTY_RATE_TYPE_INVALID

    A rate type is not ad_valorem, specific, or compound.

  • 400 MARKET_DUTY_RATE_SHAPE_INVALID

    A rate includes fields that do not belong to its selected type.

  • 400 MARKET_DUTY_RATE_REQUIRED

    An ad valorem or compound rate is missing its percentage.

  • 400 MARKET_DUTY_RATE_OUT_OF_RANGE

    A percentage rate is outside the supported range.

  • 400 MARKET_DUTY_AMOUNT_REQUIRED

    A specific or compound rate is missing its amount.

  • 400 MARKET_DUTY_RATE_PER_INVALID

    A specific or compound rate does not use kg or unit.

  • 400 MARKET_DUTY_HS_CODE_INVALID_FORMAT

    An HS code cannot be normalized to an even 2 to 12 digit code.

  • 400 MARKET_DUTY_HS_RATES_TOO_MANY

    The rule exceeds the live HS-rate limit.

  • 400 MARKET_DUTY_ORIGIN_INVALID

    An origin is invalid, matches the destination, or duplicates another origin after normalization.

Delete a duty rule

DELETE write_markets

Remove a country's duty rule and every saved rate beneath it.

Future calculations stop using the rule. Existing orders retain the duty evidence saved in their pricing snapshots. A successful deletion publishes duty_rules/delete with the rule id, market id, and country code.

Path parameters

Name Type Description
marketId required uuid

Market id.

Example: 9a1f2c3d-4e5f-6789-abcd-ef0123456789
ruleId required uuid

Duty country rule id.

Example: 7c9e4f2b-1a3d-4e5f-8b6c-2d0e1f3a4b5c

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    marketId must be a valid UUID.

  • 404 MARKET_NOT_FOUND

    The market does not exist in this store.

  • 404 DUTY_RULE_NOT_FOUND

    The duty rule does not exist in this market.

Check duty health

GET read_markets + read_products

Find catalog items checkout cannot charge duty on.

Checks every enabled duty rule in markets with duties turned on against the shippable items of active products, the same way checkout rates them. Items whose origin is the rule's destination pay no duty and are skipped. For each rule it returns counts and up to 20 example items for: missing_hs_code, missing_origin, missing_weight (only where the matching rate is charged per kg) and missing_rate (no rate for the item's origin and HS code, and no * default), plus unrated_origins, the origin countries with no matching rate and how many items each covers. currency_mismatch is true when the rule's currency differs from the serving currency of its destination country: checkout then charges no duty to that country at all. Each example's product_id, and variant_id for a variant, identify the item to fix. status is ok when a rule has nothing to fix and issues otherwise; the top-level status is issues when any rule has one. At checkout, an item that cannot be rated pays no duty and the order goes ahead; staff and API orders containing one are refused with an ORDER_DUTY_* error. The report is computed for the whole catalog and may be up to 60 seconds old; generated_at says when it was computed. Markets list responses include duty_health_available, which is false when there is nothing to check.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Webhook events#

Duty-rule events are inserted in the same database transaction as every create, update, or delete. Payloads preserve ad valorem, specific, and compound rate shapes.

Duty rule created

EVENT duty_rules/create App scope: read_markets Staff permission: markets:write

Fired when a country duty rule is created in a market.

Payload fields

Field Type Description
duty_rule.id string Always present
duty_rule.market_id string Selectable in the Payload builder
duty_rule.country_code string Selectable in the Payload builder
duty_rule.de_minimis_value string Selectable in the Payload builder

Exact non-negative imported-merchandise threshold after discounts, expressed at the destination currency precision. Domestic goods are excluded; equality is not exempt.

duty_rule.de_minimis_currency string Selectable in the Payload builder

Destination currency used by the threshold and specific/compound tariff coefficients.

duty_rule.default_duty_rates object Selectable in the Payload builder

Origin-keyed rate maps. Percentages allow two decimals; per-unit/per-kg coefficients allow four, independently of currency minor units. Calculated duties settle at currency precision with reconciled line allocations.

duty_rule.hs_rates object Selectable in the Payload builder

Origin-keyed rate maps. Percentages allow two decimals; per-unit/per-kg coefficients allow four, independently of currency minor units. Calculated duties settle at currency precision with reconciled line allocations.

duty_rule.is_enabled boolean Selectable in the Payload builder
duty_rule.created_at string Selectable in the Payload builder
duty_rule.updated_at string Selectable in the Payload builder

Duty rule updated

EVENT duty_rules/update App scope: read_markets Staff permission: markets:write

Fired when a country duty rule or its HS rates change.

Payload fields

Field Type Description
duty_rule.id string Always present
duty_rule.market_id string Selectable in the Payload builder
duty_rule.country_code string Selectable in the Payload builder
duty_rule.de_minimis_value string Selectable in the Payload builder

Exact non-negative imported-merchandise threshold after discounts, expressed at the destination currency precision. Domestic goods are excluded; equality is not exempt.

duty_rule.de_minimis_currency string Selectable in the Payload builder

Destination currency used by the threshold and specific/compound tariff coefficients.

duty_rule.default_duty_rates object Selectable in the Payload builder

Origin-keyed rate maps. Percentages allow two decimals; per-unit/per-kg coefficients allow four, independently of currency minor units. Calculated duties settle at currency precision with reconciled line allocations.

duty_rule.hs_rates object Selectable in the Payload builder

Origin-keyed rate maps. Percentages allow two decimals; per-unit/per-kg coefficients allow four, independently of currency minor units. Calculated duties settle at currency precision with reconciled line allocations.

duty_rule.is_enabled boolean Selectable in the Payload builder
duty_rule.created_at string Selectable in the Payload builder
duty_rule.updated_at string Selectable in the Payload builder

Duty rule deleted

EVENT duty_rules/delete App scope: read_markets Staff permission: markets:write

Fired when a country duty rule is deleted.

Payload fields

Field Type Description
duty_rule.id string Always present
duty_rule.market_id string Selectable in the Payload builder
duty_rule.country_code string Selectable in the Payload builder