DOCS

Catalog item workflows

Validate categories, classify HS codes, and infer export classifications for your items in a single request.

Chain workflows in one request 

Enriching a product usually takes several calls: check its categories, classify it for the countries you ship to, and determine its export control code. Called separately, each of those mutations needs the item's details, and its image, sent again, and your code has to carry each result into the next call.

Catalog item workflows remove that work. You send the item details and image once, as a draft, and then chain the steps you need as later fields of the same GraphQL mutation. Each step reads the drafts and builds on what earlier steps found. For example, when category validation corrects an item's categories, classification and export classification use the corrected categories.

How it works 

GraphQL runs the top-level fields of a mutation in order, one after another. A workflow operation always starts with catalogItemDraftsCreateWorkflow, which creates the drafts, followed by the steps you want, in the order you want them to run.

Step↕What it does↕
catalogItemDraftsCreateWorkflowCreates a draft for each item from its details and optional image. Always the first step.
categoriesValidateWorkflowValidates each draft's categories and, when they are wrong, can replace them with the top suggestion for later steps. See Category Validation.
classificationsCalculateWorkflowClassifies each draft's HS code for the ship-to countries you choose, or its export HS code (such as a Schedule B code). See Classify.
exportClassificationsInferWorkflowInfers each draft's export control classification, such as an ECCN. See Export Classification.
catalogItemsCreateFromDraftsWorkflowSaves the drafts as catalog items, with the categories and HS codes the earlier steps found.

Every step is optional except the first, so include only the ones you need.

A few rules apply to every workflow operation:

  • Drafts belong to one request. A draft exists only for the operation that created it, so every step that uses it must be in the same mutation. A later request can't read drafts from an earlier one.
  • Each step works on every draft by default. To limit a step to some drafts, pass their ids (returned by catalogItemDraftsCreateWorkflow) in that step's draftIds.
  • Send between 1 and 100 drafts per request.
  • Images are sent once. Pass each item's image as imageBase64 on its draft. Later steps reuse it, and each step's includeImage input controls whether that step uses it. The draft returns a pre-signed imageUrl that is valid for 15 minutes.

Validate, classify, and infer export classifications 

The example below validates the categories of two items, classifies their HS codes for the United Kingdom and Canada, classifies their US export HS codes, and infers their export control classifications from those export codes.

Because classificationsCalculateWorkflow runs twice, once for import codes and once for export codes, each call has an alias (importClassifications and exportClassifications) to tell their results apart.

1mutation CatalogItemEnrich($drafts: [CatalogItemDraftInput!]!) {
2 catalogItemDraftsCreateWorkflow(input: $drafts) {
3 id
4 name
5 categories
6 }
7 categoriesValidateWorkflow(input: { applySuggestion: WHEN_WRONG }) {
8 draftId
9 verdict
10 confidenceScore
11 appliedCategories
12 suggestedCategories {
13 category
14 confidence
15 }
16 }
17 importClassifications: classificationsCalculateWorkflow(
18 input: { shipToCountries: [GB, CA] }
19 ) {
20 draftId
21 categories
22 confidenceScore
23 hsCode {
24 code
25 codeType
26 countryCode
27 }
28 }
29 exportClassifications: classificationsCalculateWorkflow(
30 input: { hsCodeType: EXPORT, shipFromCountry: US }
31 ) {
32 draftId
33 hsCode {
34 code
35 codeType
36 countryCode
37 }
38 }
39 exportClassificationsInferWorkflow(
40 input: { shipFromCountry: US, exportHsCodePreference: CLASSIFICATION }
41 ) {
42 draftId
43 classificationCode
44 confidenceScore
45 exportHsCode
46 categories
47 alternates {
48 classificationCode
49 probabilityMass
50 }
51 }
52}

In the example above:

  • The t-shirt was submitted under Electronics > Cell Phones. Category validation returned WRONG and replaced its categories with the top suggestion, Apparel > Tops > T-Shirts, shown in appliedCategories.
  • Both classification steps and the export classification step used the corrected categories, so the t-shirt was classified under heading 6109 (t-shirts) rather than as an electronic device.
  • The export classification step used the EXPORT code from the classification step as each item's exportHsCode, because exportHsCodePreference is CLASSIFICATION.

Results from every step carry a draftId, so you can match them to the drafts you created. Classification returns one result for each draft and country, and may return more than one code per draft, so use hsCode.codeType and hsCode.countryCode to pick the code you need.

Control how steps build on each other 

Each step's input controls what it takes from earlier steps.

Applying category suggestions

categoriesValidateWorkflow uses applySuggestion to decide whether a suggestion replaces a draft's categories for later steps:

  • WHEN_WRONG (default) - Replaces the categories with the top suggestion when the verdict is WRONG.
  • NEVER - Reports the verdict and suggestions only. Drafts keep their categories.

To apply only confident corrections, set minimumVerdictConfidence (the minimum confidenceScore of the WRONG verdict) or minimumSuggestionConfidence (the minimum confidence of the top suggestion). When a minimum isn't met, the draft keeps its categories.

Suggestions come from your organization's category tree, so they are only as good as that tree. Each suggestion's confidence is relative to the other suggestions, so with a small or incomplete tree, a poor match can still score high. Load your full category tree before relying on WHEN_WRONG; see Manage your category tree.

The classification, export classification, and catalog item steps use the corrected categories by default. Set useValidatedCategories: false on a step to use the draft's original categories instead.

Choosing the HS codes

classificationsCalculateWorkflow classifies for the countries in shipToCountries. To produce export HS codes instead (such as US Schedule B codes), set hsCodeType: EXPORT and shipFromCountry. If you need both, call the step twice with an alias for each call, as in the example above.

exportClassificationsInferWorkflow chooses each draft's export HS code with exportHsCodePreference:

  • PROVIDED (default) - Uses the exportHsCode on the draft, and the classification step's EXPORT code only when the draft has none.
  • CLASSIFICATION - Uses the classification step's EXPORT code, and the draft's exportHsCode only when there is none.

When neither code exists, Zonos determines one as part of the export classification. Providing an export HS code gives the most reliable results.

Screening against munitions lists

By default, export classification follows your organization's export classification settings. Use settingOverride to change them for a single step. For example, set munitionsScreeningEnabled: true to screen items against the jurisdiction's munitions list (in the US, the USML) before its dual-use list (the CCL). Results then include controlList, controlListVersion, and controlTier.

exportClassificationsInferWorkflow(
  input: {
    shipFromCountry: US
    settingOverride: { munitionsScreeningEnabled: true }
  }
) {
  draftId
  classificationCode
  controlList
  controlListVersion
  controlTier
}

Note: A munitions result flags an item for compliance review. It is not a final determination.

Save the results to your catalog 

To save the drafts as catalog items, add catalogItemsCreateFromDraftsWorkflow as the last step. Each catalog item gets the categories from category validation and an HS code from classification, and returns the draftId it came from.

catalogItemsCreateFromDraftsWorkflow(
  input: { hsCodePreference: CLASSIFICATION, shipToCountry: GB }
) {
  id
  sku
  categories
  hsCode
}
  • hsCodePreference - PROVIDED (default) keeps the draft's own hsCode and uses the classification's code only when the draft has none. CLASSIFICATION prefers the classification's code.
  • shipToCountry - Chooses which country's classification supplies the HS code when the classification step ran for more than one country.

A catalog item never gets an export HS code as its hsCode. Catalog items are saved by their item key, like catalogItemCreate, so give each draft a sku or productId. A draft without one is saved as a new catalog item every time the workflow runs.

Handle errors 

Each draft succeeds or fails on its own in every step. When a draft fails, it is left out of that step's results and reported in errors with its draftId in the extensions, while the other drafts continue. The errorType tells you why:

  • BAD_REQUEST - The draft's input is invalid, such as an export HS code without digits. Fix the input before retrying.
  • INTERNAL - An unexpected error occurred.
  • UNAVAILABLE - A dependency timed out or was unreachable. Retry the request.
1mutation ExportOnly($drafts: [CatalogItemDraftInput!]!) {
2 catalogItemDraftsCreateWorkflow(input: $drafts) {
3 id
4 name
5 }
6 exportClassificationsInferWorkflow(input: { shipFromCountry: US }) {
7 draftId
8 classificationCode
9 exportHsCode
10 }
11}

A problem with a step as a whole fails that entire step. This happens, for example, when the step has no drafts to work on because catalogItemDraftsCreateWorkflow is missing from the mutation, or when draftIds names a draft that isn't part of the request.

Book a demo

Was this page helpful?


Get support·Legal docs·© 2026 Zonos