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/experimentalBecause the Experimental API can change frequently, fetch or inspect the latest GraphQL schema from this endpoint before building or updating an integration.
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
carriersandshipping_methodsqueries - Request label printing with the
label_printmutation
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:shipmentsIf 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.