Developer Resources > Examples

Overview

A webhook is a way for an app to provide other applications with real-time information. A webhook delivers data to other applications as it happens, meaning you get data immediately.

In ShipHero we have several different webhooks you can subscribe to, and when doing so, you should be receiving different kind of information, for example, if you subscribe to the Inventory Update webhook, we will be sending the webhook each time your inventory gets updated.

Note:

Although it is not often, it is possible for a webhook not to fire, and that is why your app should not rely just on receiving data from our webhooks.
The webhook delivery is not always guaranteed, so we strongly suggest implementing reconciliation jobs to periodically fetch data from ShipHero.
Our most important Queries have both thecreated_at_min and updated_at_minfilter parameters., which will allow you to build a job that fetches all resources that have been created or updated since the last time the job ran.

Available webhooks:

In the section below there are some examples of what the webhooks look like, and what the response should look like when successfully received the webhook.

 

Inventory Update

This URL is the URL that you setup on your system, so we can push updates. This webhook will be called anytime the On Hand quantity changes. The warehouse returned in the webhook body will always be the warehouse that the movement occurred in.

Webhook Body:

{
    "account_id": 7556,
    "account_uuid": "QWNjb3VudDo3NTU2",
    "webhook_type": "Inventory Update",
    "inventory": [
        {
            "sku": "100100",
            "inventory": "37",
            "backorder_quantity": "1",
            "on_hand": "45",
            "virtual": false,
            "updated_warehouse": {
                "warehouse_id": 13841,
                "warehouse_uuid": "V2FyZWhvdXNlOjEzODQx",
                "identifier": "CA",
                "inventory": "35",
                "backorder_quantity": "0",
                "on_hand": "35"
            }
        }
    ]
}

Response:

{
  "code": "200",
  "Message": "Success"
}

Shipment Update

This URL is the URL that you set up on your system, so we can push updates.

Webhook Body:

{
{
    "test": "0",
    "webhook_type": "Shipment Update",
    "fulfillment": {
        "shipment_id": 315518042,
        "shipment_uuid": "U2hpcG1lbnQ6MzE1NTE4MDQy",
        "warehouse": "Primary",
        "warehouse_id": 76733,
        "warehouse_uuid": "V2FyZWhvdXNlOjc2NzMz",
        "webhook_type": "Shipment Update",
        "partner_order_id": "test-track-url",
        "order_number": "test-track-url",
        "tracking_number": "15619819718",
        "line_items": [
            {
                "id": "test-track-url-363346570",
                "shiphero_id": 828656700,
                "quantity": 1,
                "sku": "FU2314R",
                "serial_numbers": [],
                "customs_description": "",
                "package": "Package #1",
                "lot_id": null,
                "lot_name": null,
                "lot_expiration": null
            },
            {
                "id": "test-track-url-363343850",
                "shiphero_id": 828656701,
                "quantity": 1,
                "sku": "FU3314R",
                "serial_numbers": [],
                "customs_description": null,
                "package": "Package #2",
                "lot_id": null,
                "lot_name": null,
                "lot_expiration": null
            }
        ],
        "custom_tracking_url": "",
        "package_number": 1,
        "total_packages": 2,
        "shipping_method": "Super Shipping",
        "shipping_carrier": "API - TomasFD",
        "shipping_address": {
            "name": "Tomas Two",
            "address1": "1308 DREXEL AVE",
            "address2": "APT 208",
            "address_city": "MIAMI BEACH",
            "address_zip": "33139-8126",
            "address_state": "FL",
            "address_country": "US"
        },
        "package": {
            "length": 0.39,
            "width": 0.39,
            "height": 0.39,
            "weight": 13.12
        },
        "completed": true,
        "created_at": "2022-12-26 15:29:26",
        "order_uuid": "T3JkZXI6MzI0ODcxNzI5",
        "order_gift_note": ""
    },
    "total_packages": 2,
    "packages": [
        {
            "name": "Package #1",
            "weight_in_oz": 13.12,
            "width": 0.39,
            "length": 0.39,
            "height": 0.39,
            "line_items": [
                {
                    "line_item_id": 828656700,
                    "partner_line_item_id": "test-track-url-363346570",
                    "sku": "FU2314R",
                    "product_name": "FUJIFILM XF 23mm f/1.4 R LM WR Lens",
                    "customs_description": "",
                    "tariff_code": "0",
                    "price": 899,
                    "quantity": 1,
                    "weight": 13.12,
                    "customs_value": 0,
                    "ignore_on_customs": false,
                    "country_of_manufacture": "",
                    "lot_id": null,
                    "lot_name": null,
                    "lot_expiration": ""
                }
            ],
            "shipping_label": {
                "shipping_carrier": "API - TomasFD",
                "shipping_method": "Super Shipping",
                "shipping_name": "Manual Order Shipping Method",
                "cost": 100,
                "tracking_number": "15619819718",
                "tracking_url": "https://trackingurl.com/15619819718"
            },
            "shipping_address": {
                "name": "Tomas Two",
                "address1": "1308 DREXEL AVE",
                "address2": "APT 208",
                "address_city": "MIAMI BEACH",
                "address_zip": "33139-8126",
                "address_state": "FL",
                "address_country": "US"
            },
            "box_code": "02",
            "box_id": 16651,
            "box_name": "12x7x7"
        },
        {
            "name": "Package #2",
            "weight_in_oz": 12.7,
            "width": 0.39,
            "length": 0.39,
            "height": 0.39,
            "line_items": [
                {
                    "line_item_id": 828656701,
                    "partner_line_item_id": "test-track-url-363343850",
                    "sku": "FU3314R",
                    "product_name": "FUJIFILM XF 33mm f/1.4 R LM WR Lens ",
                    "customs_description": null,
                    "tariff_code": "0",
                    "price": 799,
                    "quantity": 1,
                    "weight": 12.7,
                    "customs_value": 0,
                    "ignore_on_customs": false,
                    "country_of_manufacture": "",
                    "lot_id": null,
                    "lot_name": null,
                    "lot_expiration": ""
                }
            ],
            "shipping_label": {
                "shipping_carrier": "API - TomasFD",
                "shipping_method": "Mega Shipping",
                "shipping_name": "Manual Order Shipping Method",
                "cost": 100,
                "tracking_number": "63721453534",
                "tracking_url": "https://trackingurl.com/63721453534"
            },
            "shipping_address": {
                "name": "Tomas Two",
                "address1": "1308 DREXEL AVE",
                "address2": "APT 208",
                "address_city": "MIAMI BEACH",
                "address_zip": "33139-8126",
                "address_state": "FL",
                "address_country": "US"
            },
            "box_code": "02",
            "box_id": 16651,
            "box_name": "12x7x7"
        }
    ]
}

Response:

{
  "code": "200",
  "Message": "Success"
}

Automation Rules Webhook

Although not strictly a webhook, it is built similarly, and it will help you power up your API integrations just like any other of our webhooks.
By setting up an automation rule with this action, whenever the trigger conditions are met, we will send the payload in a POST call to the registered endpoint.
Use the addressable action data to identify what made the AR trigger on your endpoint, and continue with your workflow from there.

Automation rule action detail
Payload:

{
  "account_id": "the account id",
  "account_uuid": "the uuid of the account",
  "order_id": "the shiphero order id",
  "shop_name": "the orde shop_name",
  "order_number": "the order_number",
  "partner_order_id": "the partner_order_id",
  "action_data": "the text from the Message field in the automation rule action"
}

Order Canceled

ShipHero will call this URL when an order is canceled.

Webhook Body:

{
    "order_number": "9035013-2",
    "partner_order_id": "9035013-2",
    "fulfillment-status": "canceled",
    "order_id": 389118717,
    "order_uuid": "T3JkZXI6Mzg5MTE4NzE3",
    "shop_name": "public-api",
    "shop_order_number": "9035013-2",
    "webhook_type": "Order Canceled"
}

Response:

{
  "code": "200",
  "Message": "Success"
}

Capture Payment

ShipHero will call this URL to attempt to request a payment capture before the order is shipped. If success is returned, the order will be shipped. If a failure (HTTP code not 200 or body code not 200) is returned, shipping will be stopped, and the order will be put in Payment Hold.
This may be called multiple times after success, for example on partially shipped order or reships, so your code should account for these cases.

Please, reach out to support to have this webhook configured in your account

Webhook Body:

{
{
    "webhook_type": "Capture Payment",
    "order_number": "#123486165",
    "partner_order_number": 123486165,
    "partner_order_id": "test no status",
    "account_id": 63898,
    "shop_name": "Amazon US",
    "order_id": 397707517,
    "line_items":
    [
        {
            "id": "534534534535435345",
            "sku": "FU5014028",
            "shiphero_id": 995780973,
            "quantity": 1
        },
        {
            "id": "453454343543534",
            "sku": "FU165528",
            "shiphero_id": 995780972,
            "quantity": 1
        }
    ]
}

Response:

{
  "code": "200",
  "Message": "Success"
}

or

{
  "code": "500",
  "Status": "Failure"
}

PO Update

This URL is the URL that you setup on your system, so we can push updates. This webhook will be called anytime a purchase order is created or updated.

Webhook Body:

{
    "test": "0",
    "purchase_order": {
        "id": 1070110,
        "po_number": "PO 31",
        "po_id": 31,
        "po_uuid": "UHVyY2hhc2VPcmRlcjoxMDcwMTEw",
        "line_items": [
            {
                "id": "628e770348136",
                "quantity": 10,
                "quantity_received": 5,
                "sku": "FUXT4B",
                "vendor_id": 423049,
                "vendor_uuid": "VmVuZG9yOjQyMzA0OQ==",
                "vendor_account_number": null,
                "vendor_sku": ""
            },
            {
                "id": "628e770348139",
                "quantity": 10,
                "quantity_received": 5,
                "sku": "FU165528",
                "vendor_id": 423049,
                "vendor_uuid": "VmVuZG9yOjQyMzA0OQ==",
                "vendor_account_number": null,
                "vendor_sku": ""
            },
            {
                "id": "628e77034813b",
                "quantity": 10,
                "quantity_received": 5,
                "sku": "FU5014028",
                "vendor_id": 423049,
                "vendor_uuid": "VmVuZG9yOjQyMzA0OQ==",
                "vendor_account_number": null,
                "vendor_sku": ""
            },
            {
                "id": "628e77034813d",
                "quantity": 10,
                "quantity_received": 5,
                "sku": "FU81628WRB",
                "vendor_id": 423049,
                "vendor_uuid": "VmVuZG9yOjQyMzA0OQ==",
                "vendor_account_number": null,
                "vendor_sku": ""
            },
            {
                "id": "628e77034813e",
                "quantity": 10,
                "quantity_received": 5,
                "sku": "FU10040045",
                "vendor_id": 423049,
                "vendor_uuid": "VmVuZG9yOjQyMzA0OQ==",
                "vendor_account_number": null,
                "vendor_sku": ""
            }
        ],
        "warehouse_id": 76733,
        "status": "pending",
        "webhook_type": "PO Update"
    }
} 

Response:

{
  "code": "200",
  "Message": "Success"
}

Return Update

This URL is the URL that you setup on your system, so we can push updates. This webhook will be called anytime a return is created or updated. However, in a 3PL-Child Account relationship, this webhook will only work when registered in the Child Account. As the 3PL, you can register it at the Child Account level and point it to your own endpoint.

Webhook Body:

{
    "test": "0",
    "webhook_type": "Return Update",
    "return_id": 3394303,
    "return_uuid": "UmV0dXJuOjMzOTQzMDM=",
    "status": "pending",
    "reason": "",
    "items": [
        {
            "id": 5378501,
            "uuid": "UmV0dXJuSXRlbTo1Mzc4NTAx",
            "quantity": 50,
            "quantity_received": 0,
            "sku": "CUTENESS",
            "item_reason": "Found it cheaper",
            "restock": 0,
            "partner_line_item_id": "Order #243-355933727",
            "warehouse_id": 3141
        }
    ],
    "order_id": 272271706,
    "order_uuid": "T3JkZXI6MjcyMjcxNzA2",
    "partner_order_id": "Order #243",
    "order_number": "Order #243",
    "shop_name": "Manual Order",
    "created_at": "2022-05-24 18:34:33",
    "label_type": "Self Return",
    "label_cost": "0.00",
    "picked_up": false,
    "tracking_number": "420856539274890326147006581374",
    "date_used": null
}

Response:

{
  "code": "200",
  "Message": "Success"
}


Tote Complete

This URL is the URL that you setup on your system, so we can push updates. This webhook will be called anytime a Tote Pick is completed using the Multi Item Batch Picking or Single Item Batch Picking.

Webhook Body:

{
    "webhook_type": "Tote Complete",
    "totes": [
        {
            "tote_name": "Tote-14156034",
            "tote_uuid": "VG90ZToxNDE1NjAzNA==",
            "tote_barcode": "341504915",
            "orders": [
                {
                    "order_number": "TWO",
                    "gift_note": "",
                    "items": [
                        {
                            "quantity": 1,
                            "sku": "1234567",
                            "weight": "0.0500 oz",
                            "height": "1.00 in",
                            "width": "1.00 in",
                            "length": "1.00 in"
                        },
                        {
                            "quantity": 1,
                            "sku": "45678",
                            "weight": "0.0500 oz",
                            "height": "1.00 in",
                            "width": "1.00 in",
                            "length": "1.00 in"
                        },
                        {
                            "quantity": 1,
                            "sku": "456378",
                            "weight": "0.0500 oz",
                            "height": "1.00 in",
                            "width": "1.00 in",
                            "length": "1.00 in"
                        },
                        {
                            "quantity": 1,
                            "sku": "98765",
                            "weight": "0.0500 oz",
                            "height": "1.00 in",
                            "width": "1.00 in",
                            "length": "1.00 in"
                        }
                    ]
                }
            ]
        }
    ],
    "batch_id": "ddc68fc87baa4b9bab9f533d8e4d4531b58c4c6d0a9f755313269f4e2f396902"
}

Response:

{
  "code": "200",
  "Message": "Success"
}


Tote Cleared

This URL is the URL that you setup on your system, so we can push updates. This webhook will be called anytime a Tote is cleared from the Tote page or from within an order.

Webhook Body:

{
    "tote_id": "503901030",
    "tote_name": "Green-L",
    "reason": "manual",
    "items": [
        {
            "order_id": 240144078,
            "line_item_id": 633965574,
            "pick_id": 0,
            "sku": "FU10040045"
        },
        {
            "order_id": 240156684,
            "line_item_id": 633994555,
            "pick_id": 0,
            "sku": "FU10040045"
        },
        {
            "order_id": 240151715,
            "line_item_id": 633983940,
            "pick_id": 0,
            "sku": "FU10040045"
        },
        {
            "order_id": 240150619,
            "line_item_id": 633981282,
            "pick_id": 0,
            "sku": "FU10040045"
        },
        {
            "order_id": 240144183,
            "line_item_id": 633965820,
            "pick_id": 0,
            "sku": "FU10040045"
        },
        {
            "order_id": 240146458,
            "line_item_id": 633971225,
            "pick_id": 0,
            "sku": "FU10040045"
        },
        {
            "order_id": 240144989,
            "line_item_id": 633967729,
            "pick_id": 0,
            "sku": "FU10040045"
        },
        {
            "order_id": 240144928,
            "line_item_id": 633967563,
            "pick_id": 0,
            "sku": "FU10040045"
        },
        {
            "order_id": 240167510,
            "line_item_id": 634020166,
            "pick_id": 0,
            "sku": "FU10040045"
        },
        {
            "order_id": 240146046,
            "line_item_id": 633970191,
            "pick_id": 0,
            "sku": "FU10040045"
        },
        {
            "order_id": 224832016,
            "line_item_id": 598296059,
            "pick_id": 0,
            "sku": "FUXT4B"
        },
        {
            "order_id": 223369380,
            "line_item_id": 595859678,
            "pick_id": 0,
            "sku": "UX100VS"
        },
        {
            "order_id": 219252244,
            "line_item_id": 585045021,
            "pick_id": 0,
            "sku": "0"
        }
    ]
}

Response:

{
  "code": "200",
  "Message": "Success"
}


Order Packed Out

This URL is the URL that you setup on your system, so we can push updates. This webhook will be called anytime an order is packed out from a Tote.

Webhook Body:

{
    "webhook_type": "Order Packed Out",
    "tote_id": "14156034",
    "tote_uuid": "VG90ZToxNDE1NjAzNA==",
    "tote_name": "Tote-14156034",
    "order_id": 203849703,
    "order_uuid": "T3JkZXI6MjAzODQ5NzAz",
    "items": [
        {
            "order_id": 203849703,
            "order_uuid": "T3JkZXI6MjAzODQ5NzAz",
            "line_item_id": 549638170,
            "pick_id": 123425,
            "sku": "1122335454"
        }
    ]
}

Response:

{
  "code": "200",
  "Message": "Success"
}


Package Added

This URL is the URL that you setup on your system, so we can push updates. This webhook will be called anytime a Package is added to a Shipping Container.

Webhook Body:

{
    "test": "0",
    "fulfillment": {
        "webhook_type": "Package Added",
        "shipment_id": 168700093,
        "shipment_uuid": "U2hpcG1lbnQ6MTY4NzAwMDkz",
        "partner_order_id": "MO348",
        "order_number": "MO348",
        "warehouse": "Primary",
        "warehouse_id": 11790,
        "warehouse_uuid": "V2FyZWhvdXNlOjExNzkw",
        "shipping_label_id": 119614476,
        "shipping_label_uuid": "U2hpcHBpbmdMYWJlbDoxMTk2MTQ0NzY=",
        "package_added_at": "2021-07-24T01:50:56"
    }
}

Response:

{
  "code": "200",
  "Message": "Success"
}


Order Allocated

This URL is the URL that you setup on your system, so we can push updates. This webhook will be called anytime an Order gets allocated.

Webhook Body:

{
    "webhook_type": "Order Allocated",
    "allocation_reference": 362137624,
    "account_id": 6334,
    "account_uuid": "QWNjb3VudDo2MzM0",
    "warehouse_id": 11790,
    "warehouse_uuid": "V2FyZWhvdXNlOjExNzkw",
    "allocated_at": "2021-07-24T02:03:01",
    "order_number": "MO351",
    "order_id": 204159062,
    "order_uuid": "T3JkZXI6MjA0MTU5MDYy",
    "partner_order_id": "MO351",
    "line_items": [
        {
            "id": 550365415,
            "item_uuid": "TGluZUl0ZW06NTUwMzY1NDE1",
            "partner_line_item_id": "MO351-301706334",
            "quantity": 1,
            "sku": "1122335364",
            "is_kit_component": false,
            "created_at": "2021-07-24T02:03:01"
        }
    ]
    "ready_to_ship": 1
}

Response:

{
  "code": "200",
  "Message": "Success"
}

Order Deallocated

This URL is the URL that you setup on your system, so we can push updates. This webhook will be called anytime an Order gets deallocated.

Webhook Body:

{
    "webhook_type": "Order Deallocated",
    "allocation_reference": 362137624,
    "account_id": 6334,
    "account_uuid": "QWNjb3VudDo2MzM0",
    "order_id": 204159062,
    "order_number": "MO351",
    "order_uuid": "T3JkZXI6MjA0MTU5MDYy",
    "partner_order_id": "MO351",
    "deallocated_at": "2021-07-24T02:07:56"
}

Response:

{
  "code": "200",
  "Message": "Success"
}

Get all your registered webhooks

If you need to get a list of all the webhooks you have registered to your account, you will have to use the webhooks query:

query {
  webhooks {
    request_id
    complexity
    data {
      edges {
        node {
          id
          legacy_id
          account_id
          shop_name
          name
          url
          source
        }
      }
    }
  }
}

And the response for it should be something like this:

{
  "data": {
    "webhooks": {
      "request_id": "5f04e1fcda845a0a76d4b102",
      "complexity": 101,
      "data": {
        "edges": [
          {
            "node": {
              "id": "QXBpV2ViaG9vazoxNjE0ODc4",
              "legacy_id": 1614878,
              "account_id": "QWNjb3VudDo2MzM0",
              "shop_name": null,
              "name": "Order Canceled",
              "url": "https://someURL.x.webhook.net",
              "source": "api"
            }
          },
          {
            "node": {
              "id": "QXBpV2ViaG9vazoxNjE0Nzky",
              "legacy_id": 1614792,
              "account_id": "QWNjb3VudDo2MzM0",
              "shop_name": null,
              "name": "PO Update",
              "url": "https://someURL.x.webhook.net",
              "source": "api"
            }
          },
          {
            "node": {
              "id": "QXBpV2ViaG9vazoxNjE1MDQy",
              "legacy_id": 1615042,
              "account_id": "QWNjb3VudDo2MzM0",
              "shop_name": null,
              "name": "Return Update",
              "url": "https://someURL.x.webhook.net",
              "source": "api"
            }
          }
        ]
      }
    }
  }
}

Register a new webhook

To be able to register a new webhook you will need to use the webhook_create mutation.
If you want to update an existing webhook, you will need to delete the existing one and then add it again.

Webhooks available are:

    • Inventory Update
    • Shipment Update
    • Order Canceled
    • PO Update
    • Return Update
    • Tote Complete
    • Tote Cleared
    • Order Packed Out
    • Package Added
    • Order Allocated
    • Order Deallocated

The mutation to register a webhook could be:

mutation {
  webhook_create(
    data: {
      name: "Inventory Update"
      url: "https:someValidURL.net/"
      shop_name: "api"
    }
  ) {
    request_id
    complexity
    webhook {
      shared_signature_secret
    }
  }
}

The field name is the webhook type you want to register to, for example, Inventory Update. Use the name as written in the list above, respecting spaces and capitals.

The field shop_name is an identifier that doesn’t necessarily need to be the shop’s name. If you have more than one endpoint you need the same webhook sent to, using a different Shop Name will allow you to register a second webhook of the same type.

 

The response for it should be something like this:

{
  "data": {
    "webhook_create": {
      "request_id": "60dd12525e4d76b3ee093d7d",
      "complexity": 5,
      "webhook": {
        "shared_signature_secret": "b0b588622fb191c3d96c34c5f929fbae04b94e74"
      }
    }
  }
}

The shared_signature_secret that you will get in return is the one you will be used to validate the webhook using the HTTP_X_SHIPHERO_HMAC_SHA256

shared_signature_secret will only display once, when first registering the webhook.

If you are using a 3PL account, webhooks need to be registered on the Customer account and not the 3PL account to trigger correctly.

Un-register an existing webhook

To be able to un-register an existing webhook you will need to use the webhook_delete mutation, for example:

mutation {
  webhook_delete(data: { 
    name: "PO Update", 
    shop_name: "api" }) 
  {
    request_id
    complexity
  }
}

Generate Label Webhook

Adding carriers using the Generate Label Webhook is currently by request to us, and upon approval.
If you would like to have us register one for you, please email support@shiphero.com.

Instead of using one of the ShipHero supported carriers, we can call a URL you provide to get the label from your endpoint. The endpoint you build must accept a JSON payload and return an image/PDF.

Contact us at support@shiphero.com or via chat with the following information:

  • Endpoint URL (Something like https://someurl.com/print-label )

  • Tracking URL (Something like https://www.trackingurl.com/?MyTrakcingNumber= )

  • Name of the method (Name they want to show when choosing the method)

Then we can register that for you and when you go to ship the order, you will choose API as the carrier and the name you provided as the method, and hit Print Label to trigger the call.
The response must include an image in PNG or PDF format. We DO NOT support clean URLs, the URL sent to us must contain the file extension.
Ex. “http://yourwebsite.com/file.pdf” or “http://yourwebsite.com/file.png”
Any errors must be returned with a status code of 500 or 400.

Webhook Body:

{
    "shipping_method": "API Shipping",
    "order_id": 242662901,
    "profile": "default",
    "fulfillment_status": "pending",
    "order_number": "MO31",
    "shop_name": "Manual Order",
    "account_id": 5927,
    "partner_order_id": "MO31",
    "shipping_name": "Manual Order Shipping Method",
    "tax_type": null,
    "tax_id": null,
    "incoterms": null,
    "currency": "USD",
    "from_address": {
        "name": "ShipHero",
        "company_name": "ShipHero",
        "address_1": "123 First St.",
        "address_2": "",
        "email": "help@shiphero.com",
        "city": "Anytown",
        "state": "CA",
        "zip": "90210",
        "country": "US",
        "phone": "1234567890"
    },
    "to_address": {
        "name": "Test Order",
        "company_name": "",
        "address_1": "1 MAIN ST",
        "address_2": "",
        "email": "help@shiphero.com",
        "city": "Anytown",
        "state": "CA",
        "zip": "90210",
        "country": "US",
        "phone": "1234567890"
    },
    "packages": [
        {
            "name": "Package 1",
            "weight_in_oz": 4,
            "width": 12,
            "length": 15,
            "height": 4,
            "line_items": [
                {
                    "sku": "shiphero-socks-black",
                    "tariff_code": "00.00.00.000",
                    "price": 0,
                    "customs_description": "ShipHero Socks - Black",
                    "customs_value": "0.01",
                    "line_item_id": 639727287,
                    "quantity": 1,
                    "weight": 1.92,
                    "partner_line_item_id": "MO31-299273207",
                    "id": "MO31-299273207",
                    "country_of_manufacture": "",
                    "product_name": "ShipHero Socks - Black",
                    "name": "ShipHero Socks - Black",
                    "ignore_on_customs": false
               },
               {
                   "sku": "shiphero-socks-blue",
                   "tariff_code": "00.00.00.000",
                   "price": 0,
                   "customs_description": "ShipHero Socks - Blue",
                   "customs_value": "0.01",
                   "line_item_id": 639727288,
                   "quantity": 1,
                   "weight": 1.92,
                   "partner_line_item_id": "MO31-299273245",
                   "id": "MO31-299273245",
                   "country_of_manufacture": "",
                   "product_name": "ShipHero Socks - Blue",
                   "name": "ShipHero Socks - Blue",
                   "ignore_on_customs": false
              }
        ],
        "box_code": "custom",
        "box_id": 5612,
        "box_name": "12x15 Poly Mailer"
    },
    {
        "name": "Package 2",
        "weight_in_oz": 1.08,
        "width": 8,
        "length": 12,
        "height": 2,
        "line_items": [
            {
                "sku": "shiphero-hero",
                "tariff_code": "00.00.00.000",
                "price": 0,
                "customs_description": "ShipHero Hero ",
                "customs_value": "0.01",
                "line_item_id": 639727284,
                "quantity": 1,
                "weight": 0.92,
                "partner_line_item_id": "MO31-299273995",
                "id": "MO31-299273995",
                "country_of_manufacture": "",
                "product_name": "ShipHero Hero ",
                "name": "ShipHero Hero ",
                "ignore_on_customs": false
            },
            {
                "sku": "shiphero-knit-hat",
                "tariff_code": "00.00.00.000",
                "price": 0,
                "customs_description": "ShipHero Knit Hat ",
                "customs_value": "0.01",
                "line_item_id": 639727285,
                "quantity": 1,
                "weight": 2.19,
                "partner_line_item_id": "MO31-299273169",
                "id": "MO31-299273169",
                "country_of_manufacture": "",
                "product_name": "ShipHero Knit Hat ",
                "name": "ShipHero Knit Hat ",
                "ignore_on_customs": false
            }
        ],
        "box_code": "custom",
        "box_id": 5565,
        "box_name": "2 x 8 Poly Mailer"
       }
    ]
}

Single Package Response

{
  "code": "200",
  "shipping_method": "Ground",
  "tracking_number": "456123789",
  "cost": "5.55",
  "label": "https://url-to-label.com",
  "customs_info": "",
  "shipping_carrier": "ups",
  "tracking_url": "https://mycarrier.com/456123789"
}

Multi Package Response

Note: You can use this format response for single packages as well. 

{
    "code": "200",
    "packages":[
    {
        "name": "Package 2",
        "shipping_method": "Ground",
        "tracking_number": "987654321",
        "cost": "20.20",
        "label": "https://url-to-label.com/package2.pdf",
        "customs_info": "",
        "shipping_carrier": "ups",
        "tracking_url": "https://mycarrier.com/987654321"
    },
   {
       "name": "Package 1",
       "shipping_method": "Ground",
       "tracking_number": "123456789",
       "cost": "10.10",
       "label": "https://url-to-label.com/package1.pdf",
       "customs_info": "https://url-to-label.com/customs1.pdf",
       "shipping_carrier": "ups",
       "tracking_url": "https://mycarrier.com/123456789"
    }
  ]
}

or

{
  "code": "4xx or 5xx",
  "error": "Some validation error"
}

Response fields params:

  • shipping_carrier:
    • Non-mandatory. We will use API for all API methods.
    • varchar(45)
  • shipping_method:
    • Non-mandatory. We will use the same name sent when creating the method.
    • varchar(45)
  • cost:
    • Non-mandatory. We will use 0.00 if the field is not sent.
    • Float(6,2). Must be sent as a string.
  • tracking_number:
    • Non-mandatory. Se note below.
    • varchar(45).  We will truncate any extra characters rendering the tracking link unusable.
  • label:
    • Mandatory.
    • varchar(255)
    • We DO NOT support clean URLs, must contain the file extension.
  • customs_info:
    • Non-mandatory. We will leave it blank if not sent
    • varchar(255)
    • We DO NOT support clean URLs, must contain the file extension.
  • tracking_url:
    • Non-mandatory. See note below
    • varchar(255)

NOTE on Tracking URLs:

  • The tracking URL we use for the label is the sum of the tracking_number sent in the Generate Label Webhook response and the Tracking URL sent when creating the method.
  • If no tracking_number is sent, we will leave it blank and no tracking link will be provided.
  • If the tracking_url field is present in the response, this value will override what has been explained above.
  • If you are sending the tracking_url field, make sure to send the tracking_number field. We will use what’s on this field to set the display text for the tracking_url in the UI.

Request Verification

Webhooks data sent from ShipHero will need to be verified with the secret found within the API section of the Settings area.

Each Webhook request includes a x-shiphero-hmac-sha256 header which is generated using the app’s shared secret, along with the data sent in the request.

Generate Label Webhook uses exclusively the “default” API Secret, which is created automatically when the account is first setup

To verify that the request came from ShipHero, compute the HMAC digest according to the following algorithm and compare it to the value in the x-shiphero-hmac-sha256 header.

If they match, you can be sure that the Webhook was sent from ShipHero and the data has not been compromised.

Note that if you are using a Rack-based framework such as Ruby on Rails or Sinatra the header you are looking for is HTTP_X_SHIPHERO_HMAC_SHA256

Below is a simple example in Python, showing how one might verify a webhook request.

def verify_webhook_hmac(secret, data, hmac_signature): 
''' Compares the incoming signed request with our generated signature to verify 
source :param secret: shared secret :param data: json string of post params :param hmac_signature: String 
received from HMAC header :return: Boolean ''' 

import hmac import hashlib import base64

digest = hmac.new(secret, msg=data, digestmod=hashlib.sha256).digest()
    calculated_signature = base64.b64encode(digest).decode()

    verified = True
    if calculated_signature != hmac_signature:
        verified = False

    return verified