News

Welcome to End Point’s blog

Ongoing observations by End Point people

Use ZIP+4, except when you shouldn't

The USPS provides a handy API for looking up postal rates on the fly. Recently it started failing for code that had been working for a while, so I investigated. I found a couple of different problems with it:

  • First, the "service description" field had been "augmented" by including copyright symbols via HTML mark-up. That meant internal comparisons started to fail, so I "canonicalized" all the responses by stripping out various things from both sides of my comparison.
        $string =~ s{&(?:[a-z/;&])+}{}gis;
        $string =~ s/[^a-z]//gis;
        $string =~ s/^\s+//;
        $string =~ s/\s+$//;
        $string =~ s/\s+/ /gis;
    
  • Second, I found that the API inexplicably rejects 9-digit ZIP codes, the "ZIP+4" format. That's right, you can't look up a domestic shipping rate for a 9-digit ZIP. The documentation linked above specifically calls for 5-digit ZIPs. If you pass a 9-digit ZIP to the API, it doesn't smartly recognize that you've given it too much info and just use what it needs. Instead, it throws an error.

So the API got too clever in one regard, and not clever enough where it counts.

2 comments:

Stephen said...

It's not inexplicable. It's in the API spec. ZipOrigination and ZipDestination are specified as 5 character numeric.

This makes sense because domestic rate calculation is done from zip-to-zip not zip+4-to-zip+4.

http://www.usps.com/webtools/htm/Rate-Calculators-v1-2a.htm#_Toc281821308

Paul d'Aoust said...

That's nice that it is in the API spec, but I think more API developers would do well to embrace Postel's Prescription: "Be liberal in what you accept, and conservative in what you send."

(By the way, thank you to Jeff for pointing out these issues. I already ran into the ugly markup bits — why was it not enough to just put in the symbols? they don't even require Unicode — but I didn't know about ZIP+4.)