Skip to content

ShipStation

ShipStation multi-carrier rate quotes (v2) and order sync. The extension quotes live rates through the ShipStation v2 API across every carrier connected in the merchant's ShipStation account, pushes orders to ShipStation for fulfillment via the legacy v1 API (v2 does not support order creation yet), and pulls tracking numbers back from v2 shipments on a schedule. Use it when your warehouse runs on ShipStation.

At a glance

Extension id shipstation
Category Shipping
Version 0.2.0
Provides Shipping rate calculator strategy (shipstation), Temporal workflows and a 15-minute tracking schedule, order.placed event subscription, admin GraphQL queries and mutations
External account ShipStation account: v2 API key for rates/tracking, plus v1 API key + secret for order sync

What It Provides

  • Live multi-carrier rate quotes — registers a ShippingCalculatorStrategy named shipstation that calls POST /v2/rates/estimate and maps each estimate to a checkout rate option. The quoted amount is shipping_amount + other_amount; the request sends the total weight of all packages in ounces and the dimensions of the heaviest package.
  • Order sync — an order.placed event handler (priority 80) starts ShipStationOrderSyncWorkflow when auto_sync_orders is enabled and an API key is configured. The workflow pushes the order via the legacy v1 POST /orders/createorupdate (Basic Auth) and fails with an explicit error if v1 credentials are missing. Vectis statuses map to ShipStation statuses (createdawaiting_payment, fulfilledshipped, cancelled/refundedcancelled, everything else pre-fulfillment → awaiting_shipment).
  • Tracking pollShipStationTrackingPollWorkflow runs on Temporal schedule vectis-shipstation-tracking-poll every 15 minutes. It pages through GET /v2/shipments?shipment_status=label_purchased, matches each ShipStation shipment back to a local order by order number, and records tracking: it creates a local shipment (fulfillment mode by_order, status in_transit) when the order has none, and adds a shipment box per new tracking number.
  • Carrier and service import — the syncShipstationCarriers mutation fetches GET /v2/carriers and creates a ShippingProvider per connected carrier and a ShippingMethod per service, skipping rows that already exist (idempotent).
  • GraphQL admin operations — query shipstationSyncStatus (configured / auto-sync / tracking-poll / v1-credentials flags); mutations testShipstationConnection (lists connected carriers), syncOrderToShipstation (manual single-order push), triggerShipstationTrackingPoll (manual poll), and syncShipstationCarriers.

Setup

  1. Create (or edit) a shipping provider with carrier code shipstation under Settings > Shipping > Providers & Methods (the extension's manifest settings page is Fulfillment, /settings/fulfillment).
  2. Enter your v2 API key (API-Key header auth) and the ship-from origin postal code and country.
  3. For order sync, also enter the v1 API key and secret — the v1 API is the only one that supports order creation. Storing them in the provider config surfaces the v1_configured status flag; the sync itself reads the env pair on the worker (step 6).
  4. Click Test Connection on the Fulfillment settings page (/settings/fulfillment, ShipStation tab) — the testShipstationConnection mutation validates the v2 key you enter there by listing connected carriers.
  5. Optionally click Fetch from ShipStation on the providers page (syncShipstationCarriers) to import your connected carriers and services as shipping providers and methods.
  6. For the order-sync and tracking-poll activities (scheduled or manually triggered), set SHIPSTATION_API_KEY (and SHIPSTATION_V1_API_KEY / SHIPSTATION_V1_API_SECRET for order sync) in the Temporal worker environment — the worker activities build their client from those variables (see Operational Notes).

See Shipping & Fulfillment for how carrier strategies, zones, and methods fit together.

Configuration Reference

This extension declares no manifest config_schema. All settings live in the shipping provider's config (the ShippingProvider.config column for the provider whose carrier code is shipstation), edited from Settings > Shipping > Providers & Methods. The keys read by the extension:

Key Type Default Description
api_key string (required, secret) ShipStation v2 API key
origin_postal_code string Ship-from postal code (used when the request origin has none)
origin_country string "US" Ship-from country
auto_sync_orders boolean false Push orders to ShipStation on order.placed
tracking_poll_enabled boolean false Reported by shipstationSyncStatus; see Operational Notes
v1_api_key string (secret) Legacy v1 API key; feeds the v1_configured status flag — the sync activities read the env pair (see Operational Notes)
v1_api_secret string (secret) Legacy v1 API secret; feeds the v1_configured status flag — the sync activities read the env pair (see Operational Notes)

For local development the extension falls back to environment variables when no enabled provider row carries an api_key: SHIPSTATION_API_KEY, SHIPSTATION_ORIGIN_POSTAL, SHIPSTATION_ORIGIN_COUNTRY, SHIPSTATION_V1_API_KEY, SHIPSTATION_V1_API_SECRET (plus SHIPSTATION_AUTO_SYNC and SHIPSTATION_TRACKING_POLL for the status flags).

Permissions

  • fulfillment.shipstation.manage

Manifest permissions are upserted at boot; assigning them to roles is a manual step.

Operational Notes

  • Two APIs, two rate limits — v2 (https://api.shipstation.com, API-Key header) allows 200 requests/minute and serves rates, carriers, shipments, and fulfillments; v1 (https://ssapi.shipstation.com, Basic Auth) allows 40 requests/minute and is used only for order creation. The client retries up to 3 times on HTTP 429, honouring the Retry-After header (default backoff 2 s × attempt), then raises.
  • Worker credentials come from the environment — the Temporal activities (sync_order_to_shipstation, poll_shipstation_tracking) build their client from SHIPSTATION_API_KEY / SHIPSTATION_V1_API_KEY / SHIPSTATION_V1_API_SECRET and raise SHIPSTATION_API_KEY must be set when the v2 key is missing. They do not read the shipping provider config, so order sync and tracking polls (scheduled or manually triggered — both run as Temporal activities) require the env vars on the worker even when keys are configured in the admin.
  • Schedule runs regardless of the flag — the vectis-shipstation-tracking-poll schedule is registered unconditionally every 15 minutes; the tracking_poll_enabled key is only surfaced through the shipstationSyncStatus query, it does not gate the poll.
  • Rate estimate granularity — one estimate request covers the whole cart: total weight in ounces across all packages (a 16 oz default is sent when the packages carry no weight), dimensions from the heaviest package only.
  • Order matching for tracking — the poll matches ShipStation shipments to local orders via external_order_id (falling back to shipment_number) against the Vectis order number; shipments that don't match any local order are skipped.
  • Order payload details — a PO number is sent as customer notes (PO: <number>), internal order notes go to internalNotes, and monetary fields are serialized as floats at the API boundary (values are quantized to 2 decimal places upstream).