ShipEngine Technical Scope
The purpose of this document is to give good understanding of the flows and processes using ShipEngine REST API which lets us manage all of our shipping needs without worrying about the complexities of different carrier APIs and protocols.
Our limits are 100 requests per minute and if we hit the limit an error will occur 429 Too Many Requests
with the number of seconds we have to wait for the next request.
1. Authorisation
-
ShipEngine takes security very seriously, which is why we require all API requests to be made using HTTPS and TLS 1.1 or higher. We also give you the ability to create and revoke API keys quickly and easily via our API dashboard. To authenticate yourself to ShipEngine, you need to include an API-Key header in each API call. If you don't include a key when making an API request, or if you use an incorrect or expired key, then ShipEngine will respond with a 401 Unauthorized error.
POST /v1/addresses/validate HTTP/1.1 Host: api.shipengine.com API-Key: __YOUR_API_KEY_HERE__ Content-Type: application/json
The API key is obtained from ShipEngine Dashboard so we need to just store it in our DB
2. Create a Shipping Label
- At a minimum, you need four pieces of information to create a shipping label.
- A carrier service code (e.g.
usps_priority_mail
). - Any address that you're shipping from
- Any address that you're shipping to
- The weight of the package you're sending
- A carrier service code (e.g.
Request shipping label.
Please note if we would like to request return label we just have to set is_return_label
to true
. See this page for more details.
POST /v1/labels
POST /v1/labels HTTP/1.1
Host: api.shipengine.com
API-Key: __YOUR_API_KEY_HERE__
Content-Type: application/json
{
"shipment": {
"service_code": "usps_priority_mail",
"ship_to": {
"name": "Amanda Miller",
"phone": "555-555-5555",
"address_line1": "525 S Winchester Blvd",
"city_locality": "San Jose",
"state_province": "CA",
"postal_code": "95128",
"country_code": "US",
"address_residential_indicator": "yes"
},
"ship_from": {
"name": "John Doe",
"phone": "111-111-1111",
"company_name": "Example Corp.",
"address_line1": "4009 Marathon Blvd",
"address_line2": "Suite 300",
"city_locality": "Austin",
"state_province": "TX",
"postal_code": "78756",
"country_code": "US",
"address_residential_indicator": "no"
},
"packages": [
{
"weight": {
"value": 20,
"unit": "ounce"
}
}
]
}
}
Weight is required how ever we can also specify the dimensions of the packages optional
"dimensions": {
"unit": "inch",
"length": 12.0,
"width": 7.1,
"height": 6.0
}
Response
{
"label_id": "se-202887313",
"status": "completed",
"shipment_id": "se-202887313",
"ship_date": "2019-07-26T05:00:00.000Z",
"created_at": "2019-07-26T22:10:50.286Z",
"shipment_cost": {
"currency": "USD",
"amount": 6.86
},
"insurance_cost": {
"currency": "USD",
"amount": 0.0
},
"tracking_number": "9405511899560441854156",
"is_return_label": false,
"is_international": false,
"batch_id": "",
"carrier_id": "se-123890",
"service_code": "usps_priority_mail",
"package_code": "package",
"voided": false,
"label_format": "pdf",
"label_layout": "4x6",
"trackable": false,
"carrier_code": "stamps_com",
"tracking_status": "unknown",
"label_download": {
"pdf": "https://api.shipengine.com/v1/downloads/aFbxNUVCZ0SDHHp-BmcKjA/testlabel-202887313.pdf",
"png": "https://api.shipengine.com/v1/downloads/aFbxNUVCZ0SDHHp-BmcKjA/testlabel-202887313.png",
"zpl": "https://api.shipengine.com/v1/downloads/aFbxNUVCZ0SDHHp-BmcKjA/testlabel-202887313.zpl",
"href": "https://api.shipengine.com/v1/downloads/aFbxNUVCZ0SDHHp-BmcKjA/testlabel-202887313.pdf"
},
"form_download": null,
"insurance_claim": null,
"packages": [
{
"package_code": "package",
"weight": {
"value": 1.00,
"unit": "ounce"
},
"dimensions": {
"unit": "inch",
"length": 0.0,
"width": 0.0,
"height": 0.0
},
"insured_value": {
"currency": "usd",
"amount": 0.00
},
"tracking_number": null,
"label_messages": {
"reference1": null,
"reference2": null,
"reference3": null
}
}
]
}
From label_download
we can download the requested labels in PDF format only.
3. Create a Warehouse
Warehouses have many uses, they're necessary for manifests and also necessary if you would like to provide a different return address for a returns department that is in a different location.
Request POST /v1/warehouses
POST /v1/warehouses HTTP/1.1
Host: api.shipengine.com
API-Key: __YOUR_API_KEY_HERE__
Content-Type: application/json
{
"name": "Example Corp. East Warehouse",
"origin_address": {
"company_name": "Example Corp.",
"name": "John Doe",
"phone": "111-111-1111",
"address_line1": "4009 Marathon Blvd",
"address_line2": "Suite 300",
"city_locality": "Austin",
"state_province": "TX",
"postal_code": "78756",
"country_code": "US",
"address_residential_indicator": "no"
},
"return_address": {
"company_name": "Example Corp.",
"name": "John Doe",
"phone": "111-111-1111",
"address_line1": "4009 Marathon Blvd",
"address_line2": "Suite 300",
"city_locality": "Austin",
"state_province": "TX",
"postal_code": "78756",
"country_code": "US",
"address_residential_indicator": "no"
}
}
Response
{
"warehouse_id": "se-277331",
"name": "Example Corp. East Warehouse",
"created_at": "2018-02-12T23:48:15.387Z",
"origin_address": {
"company_name": "Example Corp.",
"name": "John Doe",
"phone": "111-111-1111",
"address_line1": "4009 Marathon Blvd",
"address_line2": "Suite 300",
"city_locality": "Austin",
"state_province": "TX",
"postal_code": "78756",
"country_code": "US",
"address_residential_indicator": "no"
},
"return_address": {
"company_name": "Example Corp.",
"name": "John Doe",
"phone": "111-111-1111",
"address_line1": "4009 Marathon Blvd",
"address_line2": "Suite 300",
"city_locality": "Austin",
"state_province": "TX",
"postal_code": "78756",
"country_code": "US",
"address_residential_indicator": "no"
}
}
4. Create Manifests
Some carriers require manifests (paper and/or electronic) to properly process shipments. Manifests help postal workers and warehouse staff to work efficiently. Creating a manifest allows the warehouse to 'close out' what they're going to send with the postal worker and move to a new grouping.
Not all carriers require manifests. Some carriers make the manifest process optional, and may offer manifests in a PDF version.
Manifest Requirements by Carrier
Carrier Name | Manifest Required? | Manifest Method |
---|---|---|
Access Worldwide | REQUIRED | |
APC | REQUIRED | PDF download |
Asendia | REQUIRED | |
Australia Post | REQUIRED[^1] | PDF download |
Canada Post | REQUIRED | PDF download |
DHL eCommerce | REQUIRED | PDF[^2] |
DHL Express AU | NO | N/A |
DHL Express Canada | NO | N/A |
DHL Express UK | REQUIRED | Electronically submitted |
DHL Express (US) | NO | N/A |
DPD | REQUIRED | N/A |
FedEx (US, CA) | Optional [^3] | PDF download |
FedEx UK | REQUIRED | PDF download |
FedEx International MailService | NO | |
FirstMile | REQUIRED | N/A |
Globegistics | REQUIRED | PDF download |
Hermes | NO | N/A |
IMEX | REQUIRED [^4] | PDF download |
LSO (Lone Star Overnight) | NO | N/A |
Newgistics | REQUIRED | N/A |
OnTrac | NO | N/A |
Parcelforce | NO | N/A |
Purolator Canada | REQUIRED [^5] | PDF download |
Royal Mail | REQUIRED | PDF download |
RR Donnelley | REQUIRED | PDF download |
Sendle | NO | N/A |
UPS (CA, UK, US) | Optional [^6] | |
UPS Mail Innovations | NO | |
USPS | Optional | PDF download |
Creating Manifests in ShipEngine
ShipEngine has two different ways to create manifests:
- Explicit Manifests Specify exactly which labels to include in the manifest, and
-
Implicit Manifests Allow ShipEngine to automatically create manifests for all packages shipped from a single warehouse on a given day. In our case we will be using option 1 Explicit Manifests One way to create manifests in ShipEngine is to explicitly specify which labels to include in the manifest. You can include up to 500 labels per manifest. Request
POST /v1/manifests HTTP/1.1 Host: api.shipengine.com API-Key: __YOUR_API_KEY_HERE__ Content-Type: application/json { "label_ids": ["se-29602037", "se-29544722", "se-29475869"] }
We simply add all label ids which we would like to manifest in the labels_ids fields but we need to make sure:
When using the label_ids
property, all the listed labels need to share the same carrier_id
, warehouse_id
, and ship_date
.
Response
{
"manifests": [
{
"manifest_id": "se-17618625",
"form_id": "se-28529731",
"created_at": "2019-07-12T13:37:39.050Z",
"ship_date": "2019-07-25T05:00:00.000Z",
"shipments": 100,
"warehouse_id": "se-28529731",
"submission_id": "9475711899564878915476",
"carrier_id": "se-123890",
"manifest_download": {
"href": "http://api.shipengine.com/v1/labels/se-28529731"
}
}
]
}