Skip to Content
APIPlaybooksAdvanced TRADE Quoteability Playbook

Advanced TRADE Quoteability Playbook

Status: Active Version: v1 Last updated: 2026-04-16

This playbook documents the deployed advanced TRADE path for one-off classification review, approval, compliance quoteability, and landed-cost readiness. It is intentionally not a fourth canonical quickstart. Use it when you already understand the base auth flow and need the reviewable single-item path rather than the TRADE feed workflow.

Companion docs:

  • Public API contract pack: docs/api/public-api-contract-v1.md
  • OpenAPI contract (current): docs/api/openapi/rgl8r-public-api-v1.3.0.yaml
  • Landed cost route contract: docs/api/landed-cost-contract-v1.md
  • Agent integration kit: docs/api/agent-integration-kit-v1.md

What this path covers

This advanced path is for callers who need to:

  1. classify a single item,
  2. route that result into the review surface,
  3. approve it through the existing one-off apply seam,
  4. evaluate compliance quote readiness for a specific corridor, and
  5. confirm that landed-cost authority is also available.

The runtime contract is modular by design:

  • POST /api/trade/classify and POST /api/trade/classify/batch remain intelligence routes.
  • POST /api/trade/classify/reviews* is the review surface.
  • POST /api/trade/classify/apply remains the single public one-off persistence seam.
  • POST /api/compliance/check returns policy/document readiness only.
  • POST /api/trade/landed-cost separately determines whether authoritative landed-cost data is available.

The classify -> review boundary

The production hardening fix in this pass is narrow and explicit.

Before the fix, callers could hit review-create validation errors because classify emitted nullable optional strings such as hs10Code: null, while review create accepted optional strings but not null for those fields.

After the fix, the published handoff contract is:

  • take a review-eligible classify result from POST /api/trade/classify,
  • add the approval identity fields,
  • if classification.needsReview !== true, also set forceReview: true,
  • send it directly to POST /api/trade/classify/reviews with no client-side artifact cleanup.

The server now normalizes the classification artifact boundary consistently for classify responses, review create ingress, and review detail/list/patch serialization.

Canonical artifact rules

Top-level optional strings are normalized from string | null | undefined to string | undefined:

  • hsCode
  • hs6Code
  • hs10Code
  • description
  • referenceDescription
  • category
  • reasoning
  • source
  • model
  • providedCodeState

Normalization rules:

  • trim strings,
  • omit when null, undefined, or empty after trim,
  • preserve non-empty strings unchanged.

Other artifact rules:

  • preserve needsReview: false exactly,
  • preserve confidence: 0 and latencyMs: 0 exactly,
  • preserve arrays exactly, including empty arrays,
  • preserve unknown passthrough fields when non-nullish,
  • omit unknown passthrough fields only when null or undefined.

latencyMs, if present, is classify-time telemetry provenance only. It reflects the original classify call, not review-create timing.

Review eligibility gate

This pass does not broaden review eligibility.

Review creation remains gated exactly as deployed:

  • direct create is allowed when classificationArtifact.needsReview === true
  • otherwise the caller must send forceReview: true

Use the term review-eligible classify result in implementation and support language. If a classify result is not review-eligible by default, the caller can still route it into the review surface by explicitly setting forceReview: true.

Approval identity requirements

Review creation requires approval-ready identity up front:

  • required: sku
  • required: originCountry
  • optional: destinationCountry

Implications:

  • sku + originCountry is enough for approval-capable one-off persistence through the existing apply seam.
  • If destinationCountry is also supplied, the approved result may additionally materialize corridor-scoped trade profile state.
  • If the original classify call omitted sku or originCountry, the classify result may remain intelligence-only, but it cannot be entered into the review queue until the caller supplies those fields at review creation.

End-to-end sequence

1. Classify

CLASSIFY=$(curl -sS -X POST "$BASE_URL/api/trade/classify" \ -H "Authorization: Bearer $RGL8R_BEARER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "description": "Cotton knit shirt for adults", "originCountry": "CN", "destinationCountry": "US" }')

The response body contains classification.

2. Create a one-off review from the raw classify artifact

If the classify result is already review-eligible (needsReview === true), you can create directly. If it is not, add forceReview: true.

REVIEW_CREATE=$(python3 - <<'PY' import json, os classification = json.loads(os.environ['CLASSIFY'])['classification'] payload = { 'sku': 'ADV-TRADE-DEMO-001', 'originCountry': 'CN', 'destinationCountry': 'US', 'productDescription': 'Cotton knit shirt for adults', 'classificationArtifact': classification, } if classification.get('needsReview') is not True: payload['forceReview'] = True print(json.dumps(payload)) PY ) REVIEW=$(curl -sS -X POST "$BASE_URL/api/trade/classify/reviews" \ -H "Authorization: Bearer $RGL8R_BEARER_TOKEN" \ -H "Content-Type: application/json" \ -d "$REVIEW_CREATE")

3. Patch the review if needed

Wave 1 patchable fields are intentionally narrow:

  • classificationArtifact
  • chosenHsCode

Nothing else is patchable.

REVIEW_ID=$(echo "$REVIEW" | python3 -c "import sys,json;print(json.load(sys.stdin)['review']['id'])") REVISION=$(echo "$REVIEW" | python3 -c "import sys,json;print(json.load(sys.stdin)['review']['revision'])") PATCHED=$(curl -sS -X PATCH "$BASE_URL/api/trade/classify/reviews/$REVIEW_ID" \ -H "Authorization: Bearer $RGL8R_BEARER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"chosenHsCode":"99038512"}')

4. Approve

Approval uses optimistic locking via revision.

PATCHED_REVISION=$(echo "$PATCHED" | python3 -c "import sys,json;print(json.load(sys.stdin)['review']['revision'])") APPROVED=$(curl -sS -X POST "$BASE_URL/api/trade/classify/reviews/$REVIEW_ID/approve" \ -H "Authorization: Bearer $RGL8R_BEARER_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"revision\":\"$PATCHED_REVISION\"}")

Under the hood, approval still flows through the existing one-off apply seam. There is no second persistence implementation.

5. Check compliance quote readiness

COMPLIANCE=$(curl -sS -X POST "$BASE_URL/api/compliance/check" \ -H "Authorization: Bearer $RGL8R_BEARER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "hsCode": "99038512", "originCountry": "CN", "destinationCountry": "US", "entityType": "SKU", "entityId": "ADV-TRADE-DEMO-001" }')

Configured-mode response fields of interest:

  • policyMode
  • quoteReadiness
  • blockingReasons
  • missingRequiredDocuments

quoteReadiness means policy/document readiness only:

  • quoteable
  • blocked
  • requires_documents
  • unconfigured

In legacy mode, the response stays shape-stable with:

  • quoteReadiness = null
  • blockingReasons = []
  • missingRequiredDocuments = []

6. Check landed cost separately

LANDED_COST=$(curl -sS -X POST "$BASE_URL/api/trade/landed-cost" \ -H "Authorization: Bearer $RGL8R_BEARER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "productValue": 100, "hsCode": "99038512", "originCountry": "CN", "destinationCountry": "US" }')

Full quoteability in Wave 1 requires both halves to pass:

  1. /api/compliance/check returns quoteReadiness = "quoteable"
  2. /api/trade/landed-cost returns status = "authoritative"

A compliance response can be quoteable while landed cost is still unavailable. That is valid Wave 1 behavior because policy/document readiness and landed-cost authority are separate gates.

Configured-mode corridor behavior

Advanced quoteability is corridor-aware.

Policy modes:

  • legacy: tenant has zero corridor rows
  • configured: tenant has one or more corridor rows

Configured-mode matching order:

  1. exact (originCountry, destinationCountry) match
  2. wildcard-origin (*, destinationCountry) match
  3. otherwise no match

There is no destination-only match.

unconfigured_corridor meaning

When a tenant is in configured mode and landed cost has no enabled exact-or-wildcard corridor match, POST /api/trade/landed-cost returns a route-level business outcome:

{ "authority": "internal", "status": "unconfigured_corridor", "breakdown": null, "reason": "no_enabled_matching_corridor", "metadata": { "policyMode": "configured", "originCountry": "CN", "destinationCountry": "US", "corridorConfigured": false } }

This is not an engine-level landed-cost status. It is a route-layer precheck that says configured quote mode exists for the tenant, but the requested corridor has not been enabled.

On the compliance side, the corresponding configured-mode miss is:

  • quoteReadiness = "unconfigured"

The obligations payload still returns normally. Only the readiness summary reflects configuration debt.

What this playbook does not change

This pass does not:

  • turn advanced TRADE into a fourth canonical quickstart,
  • add a new public approval route,
  • broaden review eligibility beyond needsReview / forceReview,
  • change the engine-level landed-cost union,
  • redefine compliance readiness as full quoteability.

It hardens the existing deployed runtime and documents the additive advanced TRADE surface that already exists.