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.


Batch object

id
string
Unique, begins with "batch_"
reference
string
An optional field that may be used in place of ID in some API endpoints
object
string
"Batch"
mode
string
"test" or "production"
state
string

The overall state. Possible values:

  • "creating"
  • "creation_failed"
  • "created"
  • "purchasing"
  • "purchase_failed"
  • "purchased"
  • "label_generating"
  • "label_generated"
num_shipments
integer
The number of shipments added
shipments
An array of batch shipments
status
object

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"
label_url
string
The label image URL
scan_form
The created ScanForm
pickup
The created Pickup
created_at
datetime
When the Batch was created
updated_at
datetime
When the Batch was last updated
Batch Object
{
  "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
}

BatchShipment object

id
string
The id of the Shipment. Unique, begins with "shp_"
reference
string
An optional field that may be used in place of ID in some API endpoints
batch_status
string
The current status. Possible values are "postage_purchased", "postage_purchase_failed", "queued_for_purchase", and "creation_failed"
batch_message
string
A human readable message for any errors that occurred during the Batch's life cycle
BatchShipment Object
{
  "batch_status": "created",
  "batch_message": null,
  "reference": null,
  "tracking_code": null,
  "id": "shp_ce0a0cf1612b4e19b67bc27613ec7c8e"
}

Create a Batch

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.

Request Parameters

shipments
i.e. [Shipment, Shipment, ...]
POST /batches
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  }'
Response
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}

Add Shipments to a Batch

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.

Request Parameters

shipments
i.e. [Shipment, Shipment, ...]
POST /batches/:id/add_shipments
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  }'
Response
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}

Remove Shipments from a Batch

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.

Request Parameters

shipments
i.e. [Shipment, Shipment, ...]
POST /batches/:id/remove_shipments
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  }'
Response
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}

Buy a Batch

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.

POST /batches/:id/buy
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":
Response
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}

Batch Labels

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

file_format
i.e. PDF
POST /batches/:id/label
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  }'
Response
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}

Manifesting (Scan Form)

A ScanForm can be created for a Batch by its id.

POST /batches/:id/scan_form
1curl -X POST https://api.easypost.com/v2/batches/batch_.../scan_form \
2  -u "EASYPOST_API_KEY":
Response
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}

Retrieve all Batches

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

before_id
i.e. batch_...
Optional pagination parameter. Only records created before the given ID will be included. May not be used with after_id.
after_id
i.e. batch_...
Optional pagination parameter. Only records created after the given ID will be included. May not be used with before_id.
start_datetime
i.e. 2016-01-02T00:00:00Z
Only return records created after this timestamp. Defaults to 1 month ago, or 1 month before a passed end_datetime.
end_datetime
i.e. 2016-01-02T00:00:00Z
Only return records created before this timestamp. Defaults to end of the current day, or 1 month after a passed start_datetime.
page_size
i.e. 5
The number of records to return on each page. The maximum value is 100, and default is 10.
sort
i.e. asc
The order in which to return records. Must be either asc or desc. Defaults to desc if not provided.
GET /batches
1curl -X GET "https://api.easypost.com/v2/batches?page_size=5" \
2  -u "EASYPOST_API_KEY":
Response
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}

Retrieve Batch

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.

GET /batches/:id
1curl -X GET https://api.easypost.com/v2/batches/batch_... \
2  -u "EASYPOST_API_KEY":
Response
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}