Welcome to our RESTful API. Here you'll find reference documentation, guides and tutorials to help you start integrating our domestic shipping platform into your app or website as quickly as possible. We can't wait to see what you build!
This is a versionless API. Advance notification of breaking changes will be available in this document and will be sent by email to our developer mailing list.
If you believe you have found a bug, or you'd like to request additional functionality (no guarantees), or you release something using this API, we'd love to hear from you: support@universalpackagesys.com
Sorry, but we are unable to answer basic HTTP programming questions with this API.
Please make sure you are properly encoding the parameters. If you are having issues with credentials failing that you know are valid, this is very likely to be the issue. If you are crafting your GET query-string or POST request-body manually, you need to URL-encode the values.
Once you’re ready to go live, please contact us so that we can set up billing and give you your live API key.
You can issue a GET
request to the root endpoint to get all the endpoint categories of the API that your account has permission to access:
GET http://domestic.universalpackagesys.com/Test.DSS/v2
All responses to requests to the API endpoints, whether successful or not, will be returned in the same type of envelope structure. That is, each response has a predictable set of keys with which you can expect to interact. The following describes how that envelope works and what it may contain.
{
"meta": {
"code": 200,
"message": null,
"type": null
},
"data": {
...
}
}
The meta
key is used to communicate extra information about the response to the developer. This object will always contain code
, a copy of the HTTP status code that has been returned. If all goes well, you'll only ever see the code
key with value 200
. However, sometimes things go wrong, and in that case you might see a response like:
{
"meta": {
"code": 400,
"type": "BadRequest",
"message": "..."
}
}
The data
key is the meat of the response. It may be either be an object itself or a list of objects, but either way this is where you'll find the data you requested. The particular data returned is described in each endpoint’s documentation.
Unset fields will be represented as a null
instead of being omitted.
We return a minified form of JSON by default, but support pretty-printing of JSON for debugging and enhanced readability.
To request pretty-printing, provide the following query parameter with your request:
?pretty=true
Set it to false
or omit the parameter entirely if you wish to receive minified JSON.
Rate limiting is by default, 100 requests per minute. All responses will include X-RateLimit-*
headers containing your current rate limit status.
...
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 99
X-RateLimit-Reset: 1372700873
...
Header | Description |
---|---|
X-RateLimit-Limit |
Total number of allowed requests in the current period. |
X-RateLimit-Remaining |
The number of remaining requests in the current period. |
X-RateLimit-Reset |
UNIX timestamp of when the current period will reset. |
HTTP responses will return a 429 Too Many Requests
status code for any request until the rate limit has dropped below the required threshold. In this situation, your application should not send any further requests until X-Rate-Limit-Reset
timestamp have elapsed.
If you need the reset timestamp in a different format, any modern programming language can get the job done. For example, if you open up the console on your web browser, you can easily get the reset time as a JavaScript Date object.
new Date(1372700873 * 1000)
// => Mon Jul 01 2013 13:47:53 GMT-0400 (EDT)
If you have need for a higher rate limit, please get in touch so that we can try and help out.
All endpoints of this API require authentication. Unauthorized requests will return 404 Not Found
, instead of 403 Forbidden
or 401 Unauthorized
. This is to prevent the accidental leakage of private information to unauthorized users.
Authenticated requests require an access_token. These tokens are unique to a verified account and should be stored securely. Access tokens may expire at any time in the future.
A typical request to the tokens endpoint looks like this:
POST http://domestic.universalpackagesys.com/Test.DSS/v2/tokens
Content-Type: application/json
{
"grant_type": "client_id",
"client_id": "{client_id}"
}
where {client_id}
should be replaced with the client identifier associated with your profile.
On success, the response from the service has the status code 200 OK
in the response header, and JSON data in the response body:
200 OK
Content-Type: application/json;charset=UTF-8
{
"meta": {
"code": 200
},
"data": {
"access_token": "NgCXRK...MzYjw",
"token_type": "Bearer",
"expires_at": 1372700873,
"refresh_token": "NgAagA...Um_SHo"
}
}
Now that you have a bearer token, you can make authenticated requests to the API. This is done by either setting the HTTP Authorization header or query string in the request.
Authorization: Bearer NgCXRK...MzYjw
GET http://domestic.universalpackagesys.com/Test.DSS/v2/endpoint?access_token=NgCXRK...MzYjw
Access tokens are deliberately set to expire after a short time, after which new tokens may be granted by supplying the refresh token originally obtained during the authentication process.
The request is sent to the tokens endpoint like this:
POST http://domestic.universalpackagesys.com/Test.DSS/v2/tokens
Content-Type: application/json
{
"grant_type": "refresh_token",
"refresh_token": "{refresh_token}"
}
where {refresh_token}
should be replaced with the refresh token attained from a previous authentication.
200 OK
Content-Type: application/json;charset=UTF-8
{
"meta": {
"code": 200
},
"data": {
"access_token": "NgCXRK...MzYjw",
"token_type": "Bearer",
"expires_at": 1372700873,
"refresh_token": "NgAagA...Um_SHo"
}
}
Note: refresh tokens cannot be reused once redeemed for a new access token