Manifest Guide

This guide will explain what manifests are, why they are important, and how to create them with the EasyPost API.

A shipping manifest is a crucial checklist of packages that are ready for pickup by a carrier. They act as an advance notice of the packages that the driver or carrier agent has to pick up from your premises. Some carriers will require a manifest before their end-of-day pickups. Even if your carrier doesn't, it's still a good idea to manifest your shipments so you can hand the carrier a single form that accounts for all of the shipments being picked up.

In EasyPost, you can create a manifest using the ScanForm object. When you create Shipment or Batch objects for your individual packages, you can include them into the ScanForm object. There are a few rules that you have to follow when creating a ScanForm

  • Refunded Shipments cannot be added.
  • Each Shipment must have the same origin address.
  • Shipments must all be dated (using the label_date option) on or after the date of the form's generation.
  • Existing ScanForms may not be updated with additional Shipments. If a ScanForm already exists, and new Shipments need to be added, a new ScanForm must be created.
  • Shipments cannot be added to more than one ScanForm
  • Shipments must be provided in the form of an array.

There are eleven attributes in the ScanForm object that provide all the information regarding your manifest:

  • id: The ID number of the ScanForm, you should record this for documentation purposes
  • object: The object, which in this case, should always read "ScanForm".
  • status: Status of the ScanForm. Possible values include "creating", "created", and "failed".
  • message: The field where we explain any possible errors.
  • address: The origin address of the shipments.
  • tracking_codes: Tracking codes associated with all shipments in the ScanForm
  • form_url: URL of the document.
  • form_file_type: File format of the document.
  • batch_id: The ID of the associated Batch, if you decided to Batch your shipments before inserting them into the ScanForm. To learn more about Batches, see our Related Links.
  • created_at: Timestamp of the ScanForm creation.
  • updated_at: Timestamp of the latest ScanForm update.

Here is an example of creating a ScanForm and listening for when the asynchronous job is complete using webhooks:

Step 1: Create a ScanForm

This is a simple example of creating a ScanForm, but many users will first create a Batch first, see the Batches Guide for an example of that.

Creating a ScanForm
curl -X POST https://api.easypost.com/v2/scan_forms \
  -u "EASYPOST_API_KEY": \
  -H 'Content-Type: application/json' \
  -d '{
    "shipments": [
      {
        "id": "shp_..."
      },
      {
        "id": "shp_..."
      }
    ]
  }'
ScanForm Response
{
  "id": "sf_e79db685aecd4c7286471ff06a27a121",
  "object": "ScanForm",
  "created_at": "2024-01-24T00:07:27Z",
  "updated_at": "2024-01-24T00:07:27Z",
  "tracking_codes": ["9405500207552011812801"],
  "address": {
    "id": "adr_8e182c46ba4c11ee8b51ac1f6bc53342",
    "object": "Address",
    "created_at": "2024-01-24T00:07:25+00:00",
    "updated_at": "2024-01-24T00:07:25+00:00",
    "name": "EasyPost",
    "company": null,
    "street1": "417 Montgomery Street",
    "street2": "5th Floor",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4153334445",
    "email": "support@easypost.com",
    "mode": "test",
    "carrier_facility": null,
    "residential": null,
    "federal_tax_id": null,
    "state_tax_id": null,
    "verifications": {}
  },
  "status": "created",
  "message": null,
  "form_url": "https://easypost-files.s3.us-west-2.amazonaws.com/files/scan_form/20240124/e872ec72373078434880f49a17e5788dcc.pdf",
  "form_file_type": null,
  "batch_id": "batch_78507c9db0574b02813cf08bd52357b5",
  "confirmation": null
}

Step 2: Receive Webhook

We'll send an Event to your Webhook URLs once the ScanForm is ready. Check for scan_form.created in the Event's description field. If you haven't read our Webhooks Guide it will show you how to handle those Events.

Webhook POST JSON

{
  "result": {
    "id": "sf_...",
    "object": "ScanForm",
    "created_at": "2015-09-30T21:00:55Z",
    "updated_at": "2015-09-30T21:00:57Z",
    "tracking_codes": [
      "9405536897846194850412",
      "9400136897846194907281",
      "9400136897846194977529"
    ],
    "address": {
      "id": "adr_tyRwEd23",
      "object": "Address",
      "created_at": "2015-09-30T21:00:55Z",
      "updated_at": "2015-09-30T21:00:55Z",
      "name": "George Costanza",
      "company": "Vandelay Industries",
      "street1": "1 E 161st St.",
      "street2": null,
      "city": "Bronx",
      "state": "NY",
      "zip": "10451",
      "country": "US",
      "phone": null,
      "email": null,
      "mode": "test",
      "carrier_facility": null,
      "residential": null,
      "federal_tax_id": null,
      "state_tax_id": null,
      "verifications": {}
    },
    "status": "created",
    "message": null,
    "form_url": "https://easypost-files.s3-us-west-2.amazonaws.com/...2c0cb9.pdf",
    "form_file_type": null,
    "batch_id": "batch_...",
    "confirmation": null
  },
  "description": "scan_form.created",
  "mode": "test",
  "previous_attributes": {},
  "created_at": "2015-09-30T21:00:57Z",
  "pending_urls": [],
  "completed_urls": ["https://www.example.com/easypost-webhook"],
  "updated_at": "2015-09-30T21:00:57Z",
  "id": "evt_...",
  "user_id": "user_...",
  "status": "in_queue",
  "object": "Event"
}