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.

Note: A Batch is created in the background for Shipments as an intermediate process to creating ScanForms. You can create a ScanForm for 1 or a group of Shipments.

Creating a ScanForm
require 'easypost'

EasyPost.api_key = ENV['EASYPOST_API_KEY']

scan_form = EasyPost::ScanForm.create(
  shipments: [
    {
      id: 'shp_...',
    },
    {
      id: 'shp_...',
    },
  ],
)

puts scan_form
ScanForm Response
{
  "id": "sf_cc2ae5bd5aa54c77b95da41d09ce66b7",
  "object": "ScanForm",
  "created_at": "2022-10-17T17:17:37Z",
  "updated_at": "2022-10-17T17:17:37Z",
  "tracking_codes": ["9405500106068143632979"],
  "address": {
    "id": "adr_98589d044e3f11edbf5dac1f6bc7bdc6",
    "object": "Address",
    "created_at": "2022-10-17T17:17:36+00:00",
    "updated_at": "2022-10-17T17:17:36+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/20221017/b1d3be3965e846dd866854e0ac6f6ef6.pdf",
  "form_file_type": null,
  "batch_id": "batch_5dd34c4b69764f8c8e6d77d72d28e8d7",
  "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"
}