Batch
The Batch
object allows you to perform operations on multiple Shipments
at once.
This includes scheduling a Pickup
, creating a ScanForm
, and consolidating labels.
Operations performed on Batches
are asynchronous and take advantage of our webhook infrastructure.
The overall state. Possible values:
- "creating"
- "creation_failed"
- "created"
- "purchasing"
- "purchase_failed"
- "purchased"
- "label_generating"
- "label_generated"
A map of statuses to the count of BatchShipment
objects with that status. Valid statuses:
- "postage_purchased"
- "postage_purchase_failed"
- "queued_for_purchase"
- "creation_failed"
Batch
was createdBatch
was last updated{
"id": "batch_94b0f73e5d3344158b588f1cac2d083c",
"object": "Batch",
"mode": "test",
"state": "creating",
"num_shipments": 1,
"reference": null,
"created_at": "2024-01-24T00:03:49Z",
"updated_at": "2024-01-24T00:03:49Z",
"scan_form": null,
"shipments": [],
"status": {
"created": 0,
"queued_for_purchase": 0,
"creation_failed": 0,
"postage_purchased": 0,
"postage_purchase_failed": 0
},
"pickup": null,
"label_url": null
}
{
"batch_status": "created",
"batch_message": null,
"reference": null,
"tracking_code": null,
"id": "shp_ce0a0cf1612b4e19b67bc27613ec7c8e"
}
A Batch
can be created with or without Shipments
.
When created with Shipments
, the initial state
will be "creating".
Once the state
changes to "created", a webhook Event
will be sent.
When created with no Shipments
, the initial state will be "created" and webhook will be sent.
Note: It is recommended to keep each batch under 1,000 shipments. This best practice helps avoid timeout errors during the batch buying process.
1curl -X POST https://api.easypost.com/v2/batches \
2 -u "EASYPOST_API_KEY": \
3 -H 'Content-Type: application/json' \
4 -d '{
5 "batch": {
6 "shipments": [
7 {
8 "id": "shp_..."
9 },
10 {
11 "id": "shp_..."
12 }
13 ]
14 }
15 }'
1{
2 "id": "batch_94b0f73e5d3344158b588f1cac2d083c",
3 "object": "Batch",
4 "mode": "test",
5 "state": "creating",
6 "num_shipments": 1,
7 "reference": null,
8 "created_at": "2024-01-24T00:03:49Z",
9 "updated_at": "2024-01-24T00:03:49Z",
10 "scan_form": null,
11 "shipments": [],
12 "status": {
13 "created": 0,
14 "queued_for_purchase": 0,
15 "creation_failed": 0,
16 "postage_purchased": 0,
17 "postage_purchase_failed": 0
18 },
19 "pickup": null,
20 "label_url": null
21}
Shipments can be added to a Batch
throughout its life cycle. Just remember that the
state change of a Batch
is asynchronous and will fire a webhook Event when the state change
is completed.
1curl -X POST https://api.easypost.com/v2/batches/batch_.../add_shipments \
2 -u "EASYPOST_API_KEY": \
3 -H 'Content-Type: application/json' \
4 -d '{
5 "shipments": [
6 {
7 "id": "shp_..."
8 },
9 {
10 "id": "shp_..."
11 }
12 ]
13 }'
1{
2 "id": "batch_848345b6ef6c4297a489fd34af7e1514",
3 "object": "Batch",
4 "mode": "test",
5 "state": "created",
6 "num_shipments": 1,
7 "reference": null,
8 "created_at": "2024-01-24T00:04:53Z",
9 "updated_at": "2024-01-24T00:04:53Z",
10 "scan_form": null,
11 "shipments": [
12 {
13 "batch_status": "postage_purchased",
14 "batch_message": null,
15 "reference": null,
16 "tracking_code": "9405500207552011812467",
17 "id": "shp_406a7ca4c34c47739093acf06ffbc4b6"
18 }
19 ],
20 "status": {
21 "created": 0,
22 "queued_for_purchase": 0,
23 "creation_failed": 0,
24 "postage_purchased": 1,
25 "postage_purchase_failed": 0
26 },
27 "pickup": null,
28 "label_url": null
29}
There could be times when a Shipment
needs to be removed from the Batch
during its life cycle.
Removing a Shipment
does not remove it from the consolidated label or ScanForm
.
1curl -X POST https://api.easypost.com/v2/batches/batch_.../remove_shipments \
2 -u "EASYPOST_API_KEY": \
3 -H 'Content-Type: application/json' \
4 -d '{
5 "shipments": [
6 {
7 "id": "shp_..."
8 }
9 ]
10 }'
1{
2 "id": "batch_f25fcb6de1254de1b3e0a3f770333292",
3 "object": "Batch",
4 "mode": "test",
5 "state": "purchased",
6 "num_shipments": 0,
7 "reference": null,
8 "created_at": "2024-01-24T00:04:55Z",
9 "updated_at": "2024-01-24T00:04:55Z",
10 "scan_form": null,
11 "shipments": [],
12 "status": {
13 "created": 0,
14 "queued_for_purchase": 0,
15 "creation_failed": 0,
16 "postage_purchased": 0,
17 "postage_purchase_failed": 0
18 },
19 "pickup": null,
20 "label_url": null
21}
Once you have added all of your Shipments
to a Batch
, issue a buy request to enqueue a background job to purchase the shipments and generate all necessary labels.
Batch Buying Criteria: To buy a batch, all shipment data must be passed to the batch at the same time the batch is created. Each shipment of a batch must have a from_address
, to_address
, parcel
, service
, carrier
, and carrier_accounts
array with the single carrier account ID associated with the service.
Purchasing may take anywhere from a few seconds to an hour, depending on the size of the batch, the carrier, and Internet weather.
1curl -X POST https://api.easypost.com/v2/batches \
2 -u "EASYPOST_API_KEY": \
3 -H 'Content-Type: application/json' \
4 -d '{
5 "batch": {
6 "shipments": [
7 "from_address": {"id": "adr_..."},
8 "to_address": {"id": "adr_..."},
9 "parcel": {"id": "prcl_..."},
10 "service": "First",
11 "carrier": "USPS",
12 "carrier_accounts": ["ca_..."]
13 ]
14 }
15 }'
16
17curl -X POST https://api.easypost.com/v2/batches/batch_.../buy \
18 -u "EASYPOST_API_KEY":
1{
2 "id": "batch_26bd321f6ba947be94a9928f7167a968",
3 "object": "Batch",
4 "mode": "test",
5 "state": "created",
6 "num_shipments": 1,
7 "reference": null,
8 "created_at": "2024-01-24T00:03:50Z",
9 "updated_at": "2024-01-24T00:03:50Z",
10 "scan_form": null,
11 "shipments": [
12 {
13 "batch_status": "queued_for_purchase",
14 "batch_message": null,
15 "reference": null,
16 "tracking_code": null,
17 "id": "shp_52b29348cf76420c8b353ab3a022a4ba"
18 }
19 ],
20 "status": {
21 "created": 1,
22 "queued_for_purchase": 0,
23 "creation_failed": 0,
24 "postage_purchased": 0,
25 "postage_purchase_failed": 0
26 },
27 "pickup": null,
28 "label_url": null
29}
One of the advantages of processing Shipments
in batches is the ability to consolidate the PostageLabel
into one file.
This can only be done once for each batch and all Shipments
must have a status of "postage_purchased".
Available label formats are "PDF", "ZPL" and "EPL2". Like converting a PostageLabel
format, if this process will change the format of the labels, they must have been created as PNG files.
Request Parameters
1curl -X POST https://api.easypost.com/v2/batches/batch_.../label \
2 -u "EASYPOST_API_KEY": \
3 -H 'Content-Type: application/json' \
4 -d '{
5 "file_format": "PDF"
6 }'
1{
2 "id": "batch_5e5323be0f8444e4b9e100a76afbc921",
3 "object": "Batch",
4 "mode": "test",
5 "state": "label_generating",
6 "num_shipments": 1,
7 "reference": null,
8 "created_at": "2024-01-24T00:04:56Z",
9 "updated_at": "2024-01-24T00:05:36Z",
10 "scan_form": null,
11 "shipments": [
12 {
13 "batch_status": "postage_purchased",
14 "batch_message": null,
15 "reference": null,
16 "tracking_code": "9405500207552011812511",
17 "id": "shp_b9419ff95a034151826c7cad52556628"
18 }
19 ],
20 "status": {
21 "created": 0,
22 "queued_for_purchase": 0,
23 "creation_failed": 0,
24 "postage_purchased": 1,
25 "postage_purchase_failed": 0
26 },
27 "pickup": null,
28 "label_url": null
29}
A ScanForm
can be created for a Batch
by its id
.
1curl -X POST https://api.easypost.com/v2/batches/batch_.../scan_form \
2 -u "EASYPOST_API_KEY":
1{
2 "id": "batch_956120999a5d4ec6b3016476029b1ffa",
3 "object": "Batch",
4 "mode": "test",
5 "state": "created",
6 "num_shipments": 1,
7 "reference": null,
8 "created_at": "2024-01-24T00:04:10Z",
9 "updated_at": "2024-01-24T00:04:11Z",
10 "scan_form": null,
11 "shipments": [
12 {
13 "batch_status": "queued_for_purchase",
14 "batch_message": null,
15 "reference": null,
16 "tracking_code": null,
17 "id": "shp_a8c6628dd39941a29093dabdea391766"
18 }
19 ],
20 "status": {
21 "created": 1,
22 "queued_for_purchase": 0,
23 "creation_failed": 0,
24 "postage_purchased": 0,
25 "postage_purchase_failed": 0
26 },
27 "pickup": null,
28 "label_url": null
29}
A list of all Batch
objects associated with the given API Key
can also be retrieved.
See the Pagination section of our docs for more details on retrieving all records when multiple pages are available.
Request Parameters
after_id
.before_id
.end_datetime
.start_datetime
.asc
or desc
. Defaults to desc
if not provided.1curl -X GET "https://api.easypost.com/v2/batches?page_size=5" \
2 -u "EASYPOST_API_KEY":
1{
2 "batches": [
3 {
4 "id": "batch_927adae9626b4c149d05e34a6d8261bd",
5 "object": "Batch",
6 "mode": "test",
7 "state": "created",
8 "num_shipments": 1,
9 "reference": null,
10 "created_at": "2024-01-23T23:54:59Z",
11 "updated_at": "2024-01-23T23:55:00Z",
12 "scan_form": null,
13 "shipments": [
14 {
15 "batch_status": "created",
16 "batch_message": null,
17 "reference": null,
18 "tracking_code": null,
19 "id": "shp_8e2cb3a6881d43f39a0bd0eb9391ecbd"
20 }
21 ],
22 "status": {
23 "created": 1,
24 "queued_for_purchase": 0,
25 "creation_failed": 0,
26 "postage_purchased": 0,
27 "postage_purchase_failed": 0
28 },
29 "pickup": null,
30 "label_url": null
31 }
32 ],
33 "has_more": true
34}
A Batch
can be retrieved by either its id
or reference
.
However it is recommended to use EasyPost's provided identifiers because uniqueness on reference
is not enforced.
1curl -X GET https://api.easypost.com/v2/batches/batch_... \
2 -u "EASYPOST_API_KEY":
1{
2 "id": "batch_05e9063986b94870818a3cc6d20df714",
3 "object": "Batch",
4 "mode": "test",
5 "state": "created",
6 "num_shipments": 1,
7 "reference": null,
8 "created_at": "2024-01-24T00:03:49Z",
9 "updated_at": "2024-01-24T00:03:49Z",
10 "scan_form": null,
11 "shipments": [
12 {
13 "batch_status": "created",
14 "batch_message": null,
15 "reference": null,
16 "tracking_code": null,
17 "id": "shp_ce0a0cf1612b4e19b67bc27613ec7c8e"
18 }
19 ],
20 "status": {
21 "created": 1,
22 "queued_for_purchase": 0,
23 "creation_failed": 0,
24 "postage_purchased": 0,
25 "postage_purchase_failed": 0
26 },
27 "pickup": null,
28 "label_url": null
29}