This is my note about how to implement the UPS tracking with the API.
Background
Last week, I needed to implement the tracking feature through the UPS API. I thought it should have been straightforward because the official documents looked organized.
https://developer.ups.com/api/reference
But it took more time than I thought. I felt there wasn’t enough information or blogs about it on the Internet. Then I decided to document what I did.
What I did
From the bottom line, use the right endpoint. One is for the test and the other one is for production. I didn’t notice there were two different URLs and spent a lot of hours on figuring out the reason why I couldn’t get the real data even if I sent a request with a real tracking number
# Test
url = "https://wwwcie.ups.com/security/v1/oauth/token"
# Production
url = "https://onlinetools.ups.com/security/v1/oauth/token"
After I set the right endpoint, I created the access token using the following endpoint.
https://developer.ups.com/api/reference#tag/OAuthClientCredentials_other
import requests
# url = "https://wwwcie.ups.com/security/v1/oauth/token"
url = "https://onlinetools.ups.com/security/v1/oauth/token"
username = 'your_client_id'
passowrd = 'your_secret'
payload = {
"grant_type": "client_credentials"
}
headers = {
"Content-Type": "application/x-www-form-urlencoded",
"x-merchant-id": "string"
}
response = requests.post(url, data=payload, headers=headers, auth=(username, password))
data = response.json()
access_token = data['access_token']
Please note 2 things here. Firstly, in the document, there are username
and password
which we need to send in basic
authentication. those mean your client id and secret which were generated when you created the App on the UPS admin page. Secondly, ”grant_type”: “client_credentials”
and ”Content-Type”: “application/x-www-form-urlencoded”
are fixed contents. I have no idea about whether we have another option or not.
Then I sent a request to the following endpoint to track my deliveries
https://developer.ups.com/api/reference#tag/Tracking_other
import time
import pprint
epoch_time = int(time.time())
tracking_nums ["your_tacking_number"]
for inquiry_number in tracking_nums:
url = "https://onlinetools.ups.com/api/track/v1/details/" + inquiry_number
epoch_time = int(time.time())
headers = {
"transId": str(epoch_time),
"transactionSrc": "testing",
"Authorization": f"Bearer {access_token}"
}
response = requests.get(url, headers=headers)
data = response.json()
assert inquiry_number == data['trackResponse']['shipment'][0]['package'][0]['trackingNumber']
print(inquiry_number, data['trackResponse']['shipment'][0]['package'][0]['currentStatus'])
If you use the wrong URL, you’ll see an AssertionError
from the bottom line of the code snippet. I was stuck in here for a few days. If you’re seeing the address Shenzhen, China, or Changi, Singapore as the response, you would be sending the request to the test URL.
I would say the UPS documents are not kind or easy to read. Because of that, I spent much more time on it than I planned. I hope my experience would help people trying to implement the same feature.
That’s it!