Skip to content
Experimental API

Experimental API

The Experimental API is a Beta-only GraphQL endpoint for customers who are testing new ShipHero API capabilities before they are added to the standard Public API.

Access is not enabled by default. If you want to use the Experimental API, request access through your Customer Success Manager (CSM). Your CSM will confirm whether your account is eligible and enable access for your account.

Once access is enabled, use the standard GraphQL endpoint:

https://public-api.shiphero.com/graphql/experimental

Because the Experimental API can change frequently, fetch or inspect the latest GraphQL schema from this endpoint before building or updating an integration.

The endpoint is called Experimental because the operations exposed here are still under testing and active development. Available queries, mutations, fields, inputs, and response shapes may change.

If you have access, please share feedback quickly with your ShipHero contact. Feedback from Beta testers helps shape the final API before it becomes generally available.

Currently Available

Today, the Experimental API can be used to:

  • Query available carriers and shipping methods with carriers and shipping_methods queries
  • Request label printing with the label_print mutation

Connected Carriers Query

Use the carriers query to retrieve the carriers and shipping methods currently available to your account.

query {
  carriers {
    request_id
    complexity
    data {
      carrier
      carrier_name
      shipping_methods {
        carrier
        carrier_name
        method
        method_name
      }
    }
  }
}

Example response:

{
  "data": {
    "carriers": {
      "request_id": "...",
      "complexity": 2,
      "data": [
        {
          "carrier": "amazon",
          "carrier_name": "Amazon",
          "shipping_methods": [
            {
              "carrier": "amazon",
              "carrier_name": "Amazon",
              "method": "UPS_PTP_2ND_DAY_AIR",
              "method_name": "UPS 2nd Day Air"
            },
            {
              "carrier": "amazon",
              "carrier_name": "Amazon",
              "method": "UPS_PTP_GND",
              "method_name": "UPS Ground"
            }
          ]
        },
        {
          "carrier": "genericlabel",
          "carrier_name": "Generic",
          "shipping_methods": [
            {
              "carrier": "genericlabel",
              "carrier_name": "Generic",
              "method": "genericlabel",
              "method_name": "genericlabel"
            }
          ]
        },
        {
          "carrier": "ups",
          "carrier_name": "UPS",
          "shipping_methods": [
            {
              "carrier": "ups",
              "carrier_name": "UPS",
              "method": "UPS Ground",
              "method_name": "UPS Ground"
            },
            {
              "carrier": "ups",
              "carrier_name": "UPS",
              "method": "UPS Next Day Air",
              "method_name": "UPS Next Day Air"
            }
          ]
        }
      ]
    }
  },
  "extensions": {
    "throttling": {
      "estimated_complexity": 2,
      "cost": 1,
      "cost_detail": {
        "carriers": {
          "items_count": 0,
          "cost": 1,
          "total_cost": 1,
          "fields": {}
        }
      },
      "user_quota": {
        "credits_remaining": 4003,
        "max_available": 4004,
        "increment_rate": 60
      }
    }
  }
}

Note

The carriers and methods returned by this query can vary by account configuration and by the current Experimental API release.

Label Print Mutation

Use label_print to request label printing for an order. The payload identifies the order, carrier, method, whether an invoice should print, and the package contents.

The mutation returns labels directly under data.label_print.labels. It does not return a top-level shipment object, but each label can include shipment data such as shipment_id and shipment_line_items when those fields are selected.

Required OAuth Scope

The label_print mutation requires the granted OAuth scope:

change:shipments

If the issued token does not include this scope, the mutation returns a permission error:

{
  "errors": [
    {
      "message": "Missing required scope(s): change:shipments",
      "operation": "label_print",
      "field": "label_print",
      "request_id": "...",
      "code": 7
    }
  ],
  "data": {
    "label_print": null
  }
}

Note

Requesting change:shipments in the OAuth flow is not enough. The issued token must actually include the granted change:shipments scope. Some OAuth clients or accounts may not be allowed to receive write scopes.

Mutation

mutation Label_print($data: PrintLabelInput!) {
  label_print(data: $data) {
    request_id
    complexity
    labels {
      id
      legacy_id
      account_id
      shipment_id
      order_id
      box_id
      box_name
      status
      tracking_number
      alternate_tracking_id
      order_number
      order_account_id
      carrier
      shipping_name
      shipping_method
      cost
      box_code
      device_id
      delivered
      picked_up
      refunded
      needs_refund
      profile
      partner_fulfillment_id
      full_size_to_print
      packing_slip
      warehouse
      warehouse_id
      insurance_amount
      carrier_account_id
      source
      created_date
      tracking_url
      package_number
      parcelview_url
      tracking_status
      in_shipping_container
      shipping_container_id
      label {
        pdf_location
        paper_pdf_location
        thermal_pdf_location
        image_location
      }
      shipment_line_items {
        edges {
          cursor
          node {
            id
            legacy_id
            line_item_id
            shipment_id
            shipping_label_id
            quantity
            line_item {
              id
              legacy_id
              sku
              partner_line_item_id
              product_id
              quantity
              price
              product_name
              option_title
              fulfillment_status
              quantity_pending_fulfillment
              quantity_shipped
              warehouse
              quantity_allocated
              backorder_quantity
              custom_options
              custom_barcode
              eligible_for_return
              customs_value
              warehouse_id
              locked_to_warehouse_id
              subtotal
              barcode
              created_at
              updated_at
              order_id
              promotion_discount
            }
          }
        }
      }
    }
  }
}

Variables

This example uses genericlabel and explicit package dimensions.

{
  "data": {
    "order_id": "{{order_id}}",
    "shipping_carrier": "genericlabel",
    "shipping_method": "genericlabel",
    "print_invoice": false,
    "packages": [
      {
        "dimensions": {
          "weight": 0.0625,
          "height": 1,
          "width": 1,
          "length": 1
        },
        "line_items": [
          {
            "line_item_id": "{{line_item_id}}",
            "quantity": 1
          }
        ]
      }
    ]
  }
}

Before calling label_print, use the carriers query to retrieve the carrier and method values available for the account. For genericlabel, the carrier result looks like this:

{
  "carrier": "genericlabel",
  "carrier_name": "Generic",
  "shipping_methods": [
    {
      "carrier": "genericlabel",
      "carrier_name": "Generic",
      "method": "genericlabel",
      "method_name": "genericlabel"
    }
  ]
}

Package Dimensions Input

PrintLabelPackageInput supports dimensions as an alternative to carrier_box_code or custom_box_id. You can also send custom_box_id instead of carrier_box_code when you want to print the label with a custom box.

The PrintLabelDimensionsInput fields are:

weight: Float!
height: Float!
width: Float!
length: Float!

Example:

{
  "dimensions": {
    "weight": 0.0625,
    "height": 1,
    "width": 1,
    "length": 1
  }
}

Response

Example response:

{
  "data": {
    "label_print": {
      "request_id": "...",
      "complexity": 15,
      "labels": [
        {
          "id": "...",
          "legacy_id": 12345,
          "shipment_id": "...",
          "order_id": "{{order_id}}",
          "status": "valid",
          "tracking_number": "",
          "order_number": "EXAMPLE-1001",
          "carrier": "genericlabel",
          "shipping_method": "genericlabel",
          "cost": "0.00",
          "warehouse": "Primary",
          "warehouse_id": "12345",
          "created_date": "2026-06-22T19:58:51",
          "tracking_url": "",
          "package_number": 1,
          "tracking_status": "UNKNOWN",
          "label": {
            "pdf_location": "https://example.com/shipping-labels/example-1001/label.pdf",
            "paper_pdf_location": "https://example.com/shipping-labels/example-1001/paper-label.pdf",
            "thermal_pdf_location": "https://example.com/shipping-labels/example-1001/thermal-label.pdf",
            "image_location": "[\"https://example.com/shipping-labels/example-1001/label.pdf\", \"https://example.com/shipping-labels/example-1001/label.png\"]"
          },
          "shipment_line_items": {
            "edges": [
              {
                "cursor": "...",
                "node": {
                  "id": "...",
                  "legacy_id": 12345,
                  "line_item_id": "{{line_item_id}}",
                  "shipment_id": "...",
                  "shipping_label_id": "...",
                  "quantity": 1,
                  "line_item": {
                    "id": "{{line_item_id}}",
                    "legacy_id": 12345,
                    "sku": "EXAMPLE-SKU",
                    "product_name": "Example Product",
                    "quantity": 1,
                    "quantity_shipped": 1,
                    "order_id": "{{order_id}}"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

Note

For generic labels, tracking_number and tracking_url may be empty strings.

Note

The image_location field is returned as a JSON-encoded string containing label asset URLs.