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
ShippingCalculatorStrategynamedshipstationthat callsPOST /v2/rates/estimateand maps each estimate to a checkout rate option. The quoted amount isshipping_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.placedevent handler (priority 80) startsShipStationOrderSyncWorkflowwhenauto_sync_ordersis enabled and an API key is configured. The workflow pushes the order via the legacy v1POST /orders/createorupdate(Basic Auth) and fails with an explicit error if v1 credentials are missing. Vectis statuses map to ShipStation statuses (created→awaiting_payment,fulfilled→shipped,cancelled/refunded→cancelled, everything else pre-fulfillment →awaiting_shipment). - Tracking poll —
ShipStationTrackingPollWorkflowruns on Temporal schedulevectis-shipstation-tracking-pollevery 15 minutes. It pages throughGET /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 modeby_order, statusin_transit) when the order has none, and adds a shipment box per new tracking number. - Carrier and service import — the
syncShipstationCarriersmutation fetchesGET /v2/carriersand creates aShippingProviderper connected carrier and aShippingMethodper service, skipping rows that already exist (idempotent). - GraphQL admin operations — query
shipstationSyncStatus(configured / auto-sync / tracking-poll / v1-credentials flags); mutationstestShipstationConnection(lists connected carriers),syncOrderToShipstation(manual single-order push),triggerShipstationTrackingPoll(manual poll), andsyncShipstationCarriers.
Setup¶
- Create (or edit) a shipping provider with carrier code
shipstationunder Settings > Shipping > Providers & Methods (the extension's manifest settings page is Fulfillment,/settings/fulfillment). - Enter your v2 API key (API-Key header auth) and the ship-from origin postal code and country.
- 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_configuredstatus flag; the sync itself reads the env pair on the worker (step 6). - Click Test Connection on the Fulfillment settings page (
/settings/fulfillment, ShipStation tab) — thetestShipstationConnectionmutation validates the v2 key you enter there by listing connected carriers. - Optionally click Fetch from ShipStation on the providers page (
syncShipstationCarriers) to import your connected carriers and services as shipping providers and methods. - For the order-sync and tracking-poll activities (scheduled or manually triggered), set
SHIPSTATION_API_KEY(andSHIPSTATION_V1_API_KEY/SHIPSTATION_V1_API_SECRETfor 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 theRetry-Afterheader (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 fromSHIPSTATION_API_KEY/SHIPSTATION_V1_API_KEY/SHIPSTATION_V1_API_SECRETand raiseSHIPSTATION_API_KEY must be setwhen 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-pollschedule is registered unconditionally every 15 minutes; thetracking_poll_enabledkey is only surfaced through theshipstationSyncStatusquery, 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 toshipment_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 tointernalNotes, and monetary fields are serialized as floats at the API boundary (values are quantized to 2 decimal places upstream).