<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: CanWeShip</title>
    <description>The latest articles on DEV Community by CanWeShip (@healer0).</description>
    <link>https://dev.to/healer0</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4122425%2Ff2034f6f-858b-4816-b07f-58dcb751585c.png</url>
      <title>DEV Community: CanWeShip</title>
      <link>https://dev.to/healer0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/healer0"/>
    <language>en</language>
    <item>
      <title>USPS can charge you $50 after the package ships. I built a free checker to catch it before you buy the label</title>
      <dc:creator>CanWeShip</dc:creator>
      <pubDate>Sat, 12 Sep 2026 17:40:18 +0000</pubDate>
      <link>https://dev.to/healer0/usps-can-charge-you-50-after-the-package-ships-i-built-a-free-checker-to-catch-it-before-you-buy-5hnj</link>
      <guid>https://dev.to/healer0/usps-can-charge-you-50-after-the-package-ships-i-built-a-free-checker-to-catch-it-before-you-buy-5hnj</guid>
      <description>&lt;p&gt;A package gets accepted at the post office counter, ships without a problem, and weeks later the shipper's account takes an adjustment: a &lt;strong&gt;$50 hazardous materials noncompliance fee&lt;/strong&gt;. Nobody warned the shipper. The counter clerk didn't catch it. The parcel was already delivered.&lt;/p&gt;

&lt;p&gt;I kept running into this story while researching USPS's dangerous goods rules, and the more I dug into the official documents, the stranger it got. So I built a tool to catch it before the label gets bought. This post is about what I found and how the tool works — the design might interest you if you build anything where correctness matters more than cleverness.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the official documents actually say
&lt;/h2&gt;

&lt;p&gt;Here's the fun part. The authoritative sources don't agree with each other — and the newest information isn't where you'd expect it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On 2026-05-15, a Federal Register document (2026-09785) described the fee as an 8-point "Hazmat Quality" check with a 100% threshold.&lt;/li&gt;
&lt;li&gt;Seven weeks later, USPS walked that back in a PostalPro Industry Alert (2026-07-07): the fee is assessed &lt;strong&gt;per package&lt;/strong&gt; through Census and Automated Package Verification (APV), by comparing four data points — Service Type Code, service icon, barcode banner text, and DOT markings.&lt;/li&gt;
&lt;li&gt;The same alert says a package that both skipped the handling fee and failed the markings check gets charged &lt;strong&gt;twice&lt;/strong&gt;. The Federal Register text only says the higher of the two.&lt;/li&gt;
&lt;li&gt;And the bit I couldn't find in any Federal Register document at all: USPS Returns shipments become subject to the fee starting &lt;strong&gt;2027-02-01&lt;/strong&gt;. That date exists only in a follow-up Industry Alert, corroborated by Postal Bulletin 22709 (a DMM revision).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the ground truth lives in three Industry Alerts, a Federal Register notice, and a Postal Bulletin — none of which a regular seller would ever think to cross-reference. Meanwhile the top Google results for "why did USPS charge me a hazmat fee" are forum threads and outdated blog posts.&lt;/p&gt;

&lt;p&gt;That gap is the whole product thesis: &lt;strong&gt;the answers exist, they're official, and they're scattered across documents that contradict each other.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://canweship.com" rel="noopener noreferrer"&gt;CanWeShip&lt;/a&gt; is a free pre-shipping checker: pick your product (perfume, power bank, laptop, dry ice, nail polish, paint, perishable food…), answer a few questions about quantity, packaging and carrier, and get USPS, UPS and FedEx side by side — ship / conditional / don't buy the label — with the exact requirements and a cited official source plus verification date on every row.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyxhdy9uzwf16sy7uuo8l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyxhdy9uzwf16sy7uuo8l.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It also refuses to guess. If a critical fact is unknown, you get &lt;code&gt;MORE_INFO_NEEDED&lt;/code&gt; or &lt;code&gt;CONDITIONAL&lt;/code&gt; with a list of exactly which facts are missing — never a confident "probably fine". For the USPS fee specifically there's a path that just says &lt;strong&gt;don't buy this label&lt;/strong&gt; before you're at the counter.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part I'd discuss with dev.to readers: no LLM in the decision path
&lt;/h2&gt;

&lt;p&gt;It's 2026, so the obvious question is why this isn't a chatbot. Three reasons:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Determinism is the product.&lt;/strong&gt; The verdicts come from a rule engine running over versioned JSON rule sets. Every rule row traces to a source ID with a verification date and a content hash, and the rule directory ships with a validation suite that rejects duplicate product IDs, conflicting aliases, and sources from unofficial domains. If someone asks "why did it say don't ship this?", the answer is a traceable chain, not a plausible paragraph.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. LLMs are on the input side, locally.&lt;/strong&gt; The AI-adjacent features — parsing text you paste from an SDS, reading battery label photos for voltage/Ah/Wh hints — run entirely in your browser. They produce &lt;em&gt;evidence cards&lt;/em&gt; with extracted values, source section, and confidence. You confirm them; only then do confirmed facts feed the deterministic engine. Photos never leave the device.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Privacy is a feature, not a promise.&lt;/strong&gt; No account. No emails. Server-side analytics are anonymous funnel events without IPs, raw URLs, or your answers. A SDS PDF you read stays local.&lt;/p&gt;

&lt;p&gt;The same rule runtime also powers a stateless API (&lt;code&gt;POST /api/v1/check&lt;/code&gt; — you send confirmed product facts, it returns the three-carrier result plus a decision trace with rule versions) and an MCP tool, so a script or agent can pre-check a cart before checkout.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest status
&lt;/h2&gt;

&lt;p&gt;It's a solo project, early. ~25 product risk profiles, US domestic, three carriers. Traffic is tiny but converting well — the people who land on it do finish checks. The gaps I know about: no batch catalog checks, no multi-item same-box compatibility, and the coverage is nowhere near "every SKU".&lt;/p&gt;

&lt;h2&gt;
  
  
  Feedback I'd genuinely value
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;If you ship batteries or flammables regularly: do the outcomes match what you're told at the counter? Disagreements are exactly what the correction form is for.&lt;/li&gt;
&lt;li&gt;If you've built anything with a "deterministic core, fuzzy shell" architecture: how do you keep the fuzzy side from leaking into the core?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The site: &lt;a href="https://canweship.com" rel="noopener noreferrer"&gt;https://canweship.com&lt;/a&gt; — try &lt;a href="https://canweship.com/?item=perfume" rel="noopener noreferrer"&gt;perfume&lt;/a&gt; or a &lt;a href="https://canweship.com/?item=power_bank" rel="noopener noreferrer"&gt;power bank&lt;/a&gt; for the fastest path to a result.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>node</category>
      <category>webdev</category>
      <category>api</category>
    </item>
  </channel>
</rss>
