As you might expect for a government organization, USPS has an old-school XML API that is publicly available.
In this short update I'll show you how to track a package using the USPS tracking API.
The first step is registering for a free developer account with USPS.
After registration, there's a short wait and you'll likely receive an email with a user ID that may look something like "123ORGNAME4567". USPS doesn't use anything fancy like API keys - your User ID is your API key.
Using NodeJs, here's how you might track a package:
const got = require('got')
const xml2json = require('xml2json')
const track = async () => {
const BASE_URI = 'http://production.shippingapis.com/ShippingAPI.dll?API=TrackV2'
const xml = xml2json.toXml({
TrackRequest: {
USERID: process.env.USPS_USER_ID
TrackID: [{ID: process.env.TEST_TRACKING_NUMBER}]
}
})
let { body } = await got(`${BASE_URI}&XML=${encodeURIComponent(xml)}`)
let data = JSON.parse(xml2json.toJson(body))
return data
}
track().then(console.log.bind(console))
In the above code snippet, I'm using got but you could just as easily use node-fetch.
To make requests against USPS' API, you essentially need to provide URL-encoded xml in the query string. So, for example:
{
TrackRequest: {
USERID: "XXXXX",
TrackId: [{ID: "92748999984327000003259997"}]
}
}
Becomes the following with xml2json conversion:
<TrackRequest USERID="XXXXX">
<TrackId ID="92748999984327000003259997"></TrackId>
</TrackRequest>
Here's how you might perform zip code lookups using the USPS Postal Code API.
const got = require('got')
const xml2json = require('xml2json')
const postalCodeLookup = async (zipCode) => {
const BASE_URI = 'http://production.shippingapis.com/ShippingAPITest.dll?API=CityStateLookup'
const xml = `
<CityStateLookupRequest USERID="XXXXX">
<ZipCode ID="0">
<Zip5>${zipCode}</Zip5>
</ZipCode>
</CityStateLookupRequest>
`
const url = `${BASE_URI}&XML=${encodeURIComponent(xml)}`
let { body } = await got(url)
return JSON.parse(xml2json.toJson(body))
}
postalCodeLookup(99501).then(console.log.bind(console))