Shippo Integration

Simple shipping API with rate shopping and discounted carrier rates.

Overview

Shippo provides a unified shipping API with access to discounted carrier rates. It's ideal for merchants who want simple shipping integration without managing individual carrier accounts.

Setup

# Connect Shippo
$ hyperfold fulfill add shippo --api-key=shippo_live_xxx
Testing connection...
 Connected to Shippo
SHIPPO CONNECTED
  Account:          acme-sports-001
  Default Carrier:  USPS
  Features:         Rate shopping, Label creation, Tracking
# View connection status
$ hyperfold fulfill show shippo
INTEGRATION: Shippo
Account:            acme-sports-001
Status:             connected
Mode:               live
CARRIERS (via Shippo)
 USPS            All services
 FedEx           All services
 UPS             All services
 DHL Express     International
METRICS (30 days)
  Labels Created:   1,456
  Avg Rate Savings: 18%
  Tracking Events:  12,450

Prerequisites

  • Shippo account (free to create)
  • API token from Shippo dashboard
  • Ship-from address configured

Rate Shopping

# Rate shopping across carriers
$ hyperfold fulfill rates \
  --provider=shippo \
  --origin="Los Angeles, CA 90001" \
  --destination="New York, NY 10001" \
  --weight=2 \
  --dimensions="10x8x4"
SHIPPING RATES: LA NYC (2 lbs, 10x8x4 in)
CARRIER          SERVICE              RETAIL    SHIPPO    SAVINGS   DELIVERY
USPS             Priority Mail        $12.80    $9.45     26%       2-3 days
USPS             First Class         $5.20     $4.15     20%       4-5 days
FedEx            Ground              $14.50    $11.20    23%       4-5 days
Best Value: USPS Priority Mail ($9.45, 2-3 days)
// Agent rate shopping
@OnACPEvent("checkout.init")
async calculateShipping(event: CheckoutEvent) {
  const rates = await this.tools.fulfillment.getRates({
    provider: "shippo",
    origin: this.getWarehouseAddress(event.items),
    destination: event.shipping_address,
    parcels: this.calculateParcels(event.items)
  });
  return {
    shipping_options: rates.map(rate => ({
      id: rate.service,
      name: rate.carrier + " " + rate.service_name,
      price: rate.amount,
      delivery_estimate: rate.estimated_days + " days"
    })),
    selected: rates[0].service
  };
}

Supported Carriers

CarrierServicesDiscount
USPSPriority, First Class, ExpressUp to 40%
FedExGround, Express, OvernightUp to 30%
UPSGround, 2Day, Next DayUp to 25%
DHL ExpressInternational ExpressUp to 35%

Label Creation

# Create shipping labels
$ hyperfold fulfill label create \
  --provider=shippo \
  --order=ord_xyz789
 Label created
SHIPPING LABEL
  Tracking:         9400111899223456789012
  Carrier:          USPS Priority Mail
  Cost:             $9.45
# Batch label creation
$ hyperfold fulfill label batch \
  --provider=shippo \
  --orders=ord_001,ord_002,ord_003
// Agent label creation workflow
@OnACPEvent("order.confirmed")
async createShippingLabel(event: OrderEvent) {
  const shipment = await this.tools.fulfillment.createShipment({
    provider: "shippo",
    address_from: this.warehouse.address,
    address_to: event.order.shipping_address,
    parcels: [{
      length: 10, width: 8, height: 4,
      distance_unit: "in",
      weight: event.order.total_weight,
      mass_unit: "lb"
    }]
  });
  const rate = shipment.rates.find(r => r.service === event.shipping_service);
  const label = await this.tools.fulfillment.createLabel({
    provider: "shippo",
    rate_id: rate.object_id
  });
  return {
    tracking_number: label.tracking_number,
    label_url: label.label_url,
    carrier: label.carrier_account
  };
}

Tracking

# Configure tracking
$ hyperfold fulfill tracking enable shippo
# Track a shipment
$ hyperfold fulfill track 9400111899223456789012
TRACKING: 9400111899223456789012
Carrier:            USPS
Service:            Priority Mail
Status:             In Transit
Est. Delivery:      Jan 25, 2025
// Tracking webhooks in agent
@OnTrackingEvent("delivered")
async handleDelivery(event: TrackingEvent) {
  await this.tools.orders.updateStatus(event.order_id, "delivered");
  await this.notifyCustomer({
    type: "delivered",
    tracking: event.tracking_number,
    delivery_time: event.timestamp
  });
}
@OnTrackingEvent("exception")
async handleException(event: TrackingEvent) {
  await this.alertOps({
    type: "shipping_exception",
    order_id: event.order_id,
    message: event.status_details
  });
}