Explore this content on our NEW Developer Docs website.

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
<?php

$client = new \EasyPost\EasyPostClient('EASYPOST_API_KEY');

$scanForm = $client->scanForm->create([
    'shipments' => [
        ['id' => 'shp_...'],
        ['id' => 'shp_...'],
    ]
]);

echo $scanForm;
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"
}