Skip to main content

Automated Order Geo Routing

How automatic warehouse routing works, how to enable it per store, and how to put it through its paces. For customers and the support team.

🎯 What this feature does

SKULabs automatically assigns each order line item to the closest warehouse with stock based on the customer's shipping ZIP. It works across every sales channel (Shopify, Amazon, eBay, Walmart, BigCommerce, WooCommerce, etc.) and manual orders. Pickers only see the items routed to their warehouse, so the picking workflow stays clean and per-warehouse β€” even when a single order ends up split across multiple locations.


Why it matters

  • Faster delivery β€” items leave from the warehouse closest to the buyer.

  • Lower shipping cost β€” shorter zones, less weight-distance overhead.

  • Cleaner picking β€” each warehouse only sees the items it owns on the order.

  • Channel-agnostic β€” same logic on Shopify, Amazon, eBay, Walmart, and manual orders.

  • Safe by default β€” if routing can't decide, the order still imports and is flagged for review. Nothing is blocked.


How it works

The routing calculation

When an order comes in, the system:

  1. Reads the customer's ZIP from the shipping address (handles zip, postal_code, postalCode, and strips ZIP+4 suffixes like 10001-1234 down to 10001).

  2. Looks up coordinates for that ZIP from a built-in database of ~42,500 US ZIP codes.

  3. Measures the great-circle distance from the customer to every warehouse that has coordinates configured.

  4. Ranks warehouses from closest to farthest.

  5. For each line item, assigns the closest warehouse with enough stock. If no warehouse has stock, the closest eligible warehouse is assigned anyway so the item still has a home.

Each item on the order can be routed to a different warehouse. Example: a Denver customer orders A and B. Item A is only in stock at LA, item B is only in stock at Chicago β€” Item A goes to LA, Item B goes to Chicago, all on one order.

Dropshipped items (Amazon FBA, Walmart WFS, or anything channel-marked as dropshipped) are skipped β€” they're fulfilled externally and never get a warehouse assignment from geo-routing.

Split fulfillment by quantity

When no single warehouse has enough stock to cover the full quantity, geo-routing splits the item across multiple warehouses:

  1. Walk warehouses from closest to farthest.

  2. Take min(remaining qty, free stock) from each, until the order qty is satisfied.

  3. If stock runs short, the remaining quantity stacks onto the closest warehouse.

Each split allocation becomes a separate line on the order so the warehouses can pick independently.

The ZIP data foundation

Coordinates come from two trusted, publicly available sources, refreshed automatically:

Source

Records

Role

License

HUD population-weighted centroids

~29,300

Primary β€” coordinates represent where people actually live within each ZIP

US Government (free)

GeoNames

~13,200 supplemental

Fills gaps β€” PO Box ZIPs, military ZIPs, unusual codes HUD doesn't cover

Creative Commons 4.0

The database refreshes automatically on the 1st of every month at 3:00 AM UTC. Warehouse coordinates are set automatically when you save a warehouse address


How to enable & configure

Geo-routing is configured per store from a dedicated settings page. There's no single account-wide checkbox β€” each connected store decides whether routing runs for its orders and which warehouses are eligible.

The dedicated page β€” Settings β†’ Inventory β†’ Geo Route

The Geo Route page lists every active store with its current routing status (green check / red ban), the warehouse summary, and a pencil icon to edit. A question-mark icon in the header opens a help box that explains priority warehouse, Disable Split Geo Routing, and the rule actions.

Editing a store

Click the pencil on a store row to open the Geo Route Settings modal. From the modal:

  1. Pick eligible warehouses. Every list always shows all the account's warehouses β€” orders from this store can be geo-routed to any of them. The layout depends on whether the channel exposes multiple fulfillment locations:

    • Multi-location stores (Shopify, Amazon, Square, etc.) β€” the warehouse list is grouped by channel location. Each channel location has its own draggable list. This lets you express, for example, "for Shopify-NY use WH-East first, then WH-West; for Shopify-LA use WH-West first, then WH-East".

    • Single-location stores (eBay, etc.) β€” the warehouse list is flat (one ordered list, no grouping) because there's only one channel location to configure. The list still contains every warehouse, and orders can route to any of them based on geographic proximity.

  2. Drag rows to set priority order. The first warehouse in each list is the priority warehouse for that location. The remaining warehouses act as the routing chain β€” closer wins among them when priority can't fulfill.

  3. Toggle the three switches:

    • Enable geo-routing for this store β€” turns the whole engine on for this store.

    • Enable priority warehouse β€” when on, the priority warehouse wins over closest-with-stock if it can cover the full qty. When off, drag handles dim to ~35% opacity and reordering is disabled.

    • Disable Split Geo Routing β€” when on, geo-routing assigns the entire order to a single warehouse. See the "Single-warehouse mode" section below.

  4. Save. The store row updates immediately with the new status and warehouse summary.

Single-warehouse mode (Disable Split Geo Routing)

When Disable Split Geo Routing is on for a store:

  • Geo-routing finds the closest single warehouse that can fulfill every item in the order β€” that's the success path. Reason code: closest_with_full_stock_no_split (or priority_warehouse_no_split if priority covered it).

  • If no single warehouse can fulfill the entire order, routing falls back to the closest warehouse that can fulfill the most items and tags the order Failed Geo-Routing with a log entry explaining the partial-fulfillment fallback. Reason code: disable_split_partial_fallback.

  • This is the right mode when an account cannot tolerate split shipments and prefers a known failure mode they can react to.

What happens when you turn geo-routing on (for a store)

  • New orders syncing from that store route automatically.

  • Manually created orders for that store route the moment they're saved.

  • All existing open (unstarted) orders for that store are routed in the background.

What happens when you turn it off (for a store)

  • Geo-routing assignments are cleared from open orders for that store.

  • Items you manually assigned to a warehouse are preserved β€” only auto-routed assignments are wiped.

  • The picking UI keeps grouping by warehouse whenever items have a warehouse assignment.

  • Users can still manually reassign warehouses from the picking interface.

Before you enable, make sure

  1. At least two warehouses are configured (one-warehouse setups gain nothing).

  2. Each warehouse has a valid US ZIP in its address.

  3. Inventory is tracked at each warehouse so stock levels are accurate.

  4. For multi-location channels, channel locations have synced into SKULabs so the modal can group warehouses by location.


Channel orders vs. manual orders

Channel orders (Shopify, Amazon, eBay, Walmart, etc.)

Geo-routing runs as part of the sync pipeline. After each order is saved, items receive a warehouse assignment and a reason code. Fully automatic β€” no user action.

Manual orders

The order is saved first, then geo-routing runs on that single order. The warehouse assignment appears immediately. If routing fails (e.g., no ZIP), the order is still created and just flagged for review.

Manual warehouse override (always available)

Whether geo-routing is on or off, users with the reassign permission can change a warehouse from the picking interface:

  • Reassign an entire warehouse section to a different warehouse (section-level dropdown).

  • Reassign an individual item to a different warehouse (per-item dropdown).

  • Reassign a partial quantity β€” the system splits the line, creating a new line for the moved quantity.

Manual reassignments are tagged manual and preserved on subsequent re-routes unless someone forces a re-route.

Manual re-route

For unstarted orders, users can ask the system to recalculate routing. Three entry points:

  • Single order β€” order page menu β†’ "Re-route order". Preserves manual warehouse overrides on individual lines. Works on both Channel orders and Manual orders.

  • Bulk re-route β€” Orders β†’ Processing β†’ select orders β†’ "Bulk re-route orders". Always uses force mode β€” manual overrides are cleared. The bulk trigger is hidden entirely for accounts that have no stores with geo-routing enabled. Works on both Channel orders and Manual orders.

  • Waiting for the next channel sync β€” works for Channel orders only. Each sync cycle re-applies geo-routing to that channel's open orders. Manual orders do not get this auto-retry β€” there's no sync cycle for a Manual store, so a Manual order that needs re-routing after a fix has to be re-routed via the single or bulk action above (or by editing the Manual store's Geo Route config, which auto-re-routes all of its open orders in the background).

If an order has moved past unstarted status, both re-route paths refuse with "Only unstarted orders can be re-routed."

When does geo-routing run? β€” quick reference

Trigger

Channel orders

Manual orders

Order created / synced in

βœ“ runs once

βœ“ runs once

Next channel sync

βœ“ re-runs each cycle

β€” (no sync cycle exists)

Store's Geo Route config changes

βœ“ re-routes all open orders for that store

βœ“ re-routes all open orders for that store

User clicks "Re-route order" (single)

βœ“ preserves manual overrides

βœ“ preserves manual overrides

User clicks "Bulk re-route orders"

βœ“ always forces (clears manual overrides)

βœ“ always forces (clears manual overrides)

Stock levels change

β€” no auto-retry

β€” no auto-retry

Ship-to address edited on the order

β€” no auto-retry (use Re-route order)

β€” no auto-retry (use Re-route order)


Multi-location channels (Shopify, Square, etc.)

When a channel supports multiple fulfillment locations, warehouse links decide which SKULabs warehouses are eligible:

  • Each channel location maps to one or more SKULabs warehouses.

  • When an order item carries a channel location ID, routing is restricted to the warehouses linked to that location.

  • If a location has no linked warehouses, routing falls back to the store's warehouse list, then to all warehouses with coordinates.

When warehouse links change, all open orders for that store are automatically re-routed in the background.


Priority warehouse (per store)

Each store can prefer a specific warehouse even when it isn't the closest. Set it from the Geo Route page β€” the first warehouse in the list under each location (multi-location stores) or in the flat list (single-location stores) is the priority warehouse.

The Enable priority warehouse toggle on the same modal turns the feature on/off for that store. When off, drag handles dim and the ordering is ignored β€” closest-with-stock takes over.

Priority wins only when the warehouse has enough stock to fulfill the full quantity (or the full order, in single-warehouse mode). If it can't, routing falls back to the standard closest-with-stock logic. Priority is per-item under split mode, so one order can mix priority-routed items and closest-routed items.


Shipping rules can override routing

Shipping rules let customers selectively override geo-routing per condition β€” useful for "always send TX to FL", "always split CO between MA and FL", "skip routing for FL orders", or "this SKU stays in its channel location". Create rules from Settings β†’ Shipping β†’ Rules; each rule has filters (state, ZIP, store, channel tag, SKU, item tag, etc.) and one of the actions below.

Available rule actions

Action

What it does

Apply manual Geo Route for Order

Pins the order's fulfillment to a chosen warehouse, with optional fallbacks. Cascades through primary β†’ fallback β†’ fallback if the previous can't cover the qty. Reason: rule

Apply manual Split Geo Route for Order

Greedy split across primary + fallback warehouses. Reason: rule

Do not apply Geo Route for order

Skips routing for the whole order β€” items keep the channel-assigned warehouse

Do not apply Geo Route for item

Skips routing for matched items only. Supports item-level filters like Item SKU, Item Tag, Kit SKU.

Do not Geo Route split orders

Forces the matched order into single-warehouse mode for this run only

Apply Geo Route for Order

Re-enables splitting for the matched order even when the per-store Disable Split Geo Routing toggle is on

Rules win over priority and closest-with-stock β€” they're a deliberate override. The activity log captures which rule applied so support can trace any unexpected routing.

Rule precedence & conflict detection

  • No-split beats allow-split. If both Do not Geo Route split orders and Apply Geo Route for Order match the same order, the no-split rule wins.

  • Conflict detection β€” rules that would route the same order to different outcomes are flagged in the rules table as "Conflicting with: <other rule>". Identical rules (same fingerprint) are treated as redundant, not conflicting.

  • Tag rule ping-pong β€” rules that add a tag and rules that remove the same tag are now flagged against each other.

  • Duplicate-log suppression β€” manual Geo Route rules no longer re-log on every sync. A per-rule record tracks the last chosen warehouse; the log is only appended when the chosen warehouse changes.


Picking workflows

Heads up: Whether picking is grouped by warehouse depends on the store. Stores with Geo Route enabled get the grouped layout automatically. Stores without Geo Route can opt in via Integration Settings β†’ Fulfillment Settings β†’ "Group order lines by assigned fulfillment locations" (per-store checkbox). When off, the store uses the flat picking table even if items have warehouse assignments. Manual warehouse reassignment from the picking interface is always available.

Single order picking

Items are grouped by their assigned warehouse, each group with a section header:

  • Items within a group only show picking locations from the assigned warehouse.

  • Pickable items and unpickable items are visually separated.

  • Items that couldn't be routed appear in an "Unassigned Warehouse" section at the bottom.

Batch picking

  • Steps are sorted by warehouse first, then by zone/location within each warehouse.

  • Warehouse headers visually separate items in the step list.

  • The warehouse name appears in the bin header during the active step.

  • The location dropdown only offers bins from the assigned warehouse.

  • "Skip unpickable items" auto-skips items with no pickable location in their assigned warehouse.


Showing pickers only their items

The system filters items down to what each warehouse user is responsible for through three layers:

1. User warehouse filters

In each user's profile, "Picking warehouses" controls which warehouses they can see locations from. A user assigned only to "East Coast Warehouse" will only see East Coast locations everywhere in the app.

2. Geo-routing warehouse restriction

On top of the user filter, each item's picking locations are restricted to the single warehouse it was routed to. This prevents picking the wrong unit.

3. "Hide unpickable items" preference

A per-user preference. When on, items that have no picking locations in the user's warehouses are completely hidden during picking.


Failure handling

Geo-routing is designed to never block order processing. If something goes wrong, the order still imports β€” it just lands with a clear reason code and (where applicable) a "Failed Geo-Routing" tag.

Failure

What happens

Reason code

Customer ZIP missing

Order tagged "Failed Geo-Routing"

missing_postal_code

ZIP not in database

Order tagged "Failed Geo-Routing"

unknown_postal_code

No warehouses have coordinates

Order tagged "Failed Geo-Routing"

no_warehouses_with_coordinates

Non-US shipping address

Items skipped, no assignment

non_us_address

No warehouse has stock for an item

Closest warehouse with a tracked entry assigned (Tier 2 fallback)

closest_linked_no_stock

Item not tracked at any eligible warehouse

Closest eligible warehouse assigned (Tier 3 fallback)

closest_linked_untracked

Closest warehouse has partial stock

Closest with some stock assigned

closest_with_partial_stock

Item split across multiple warehouses

Split into multiple lines

split_across_warehouses

Closest warehouse has full stock

Assigned to closest with sufficient free stock (success)

closest_with_stock

Priority covers full qty

Assigned to the priority warehouse (success)

priority_warehouse_with_stock

Single-warehouse mode β€” one warehouse can fulfill everything

Assigned to closest warehouse that can fulfill every item

closest_with_full_stock_no_split

Single-warehouse mode β€” priority covers everything

Assigned to priority warehouse

priority_warehouse_no_split

Single-warehouse mode β€” no warehouse can fulfill everything

Assigned to closest warehouse that can fulfill the most items; order tagged "Failed Geo-Routing"

disable_split_partial_fallback

Rule forces a warehouse or split

Assigned by the shipping rule

rule

Manual assignment by a user

Preserved on single re-routes (cleared on bulk force re-route)

manual

When routing succeeds on a later attempt (e.g., after fixing warehouse coordinates), the "Failed Geo-Routing" tag is automatically removed.


FAQs

Why is my order tagged "Failed Geo-Routing"?
The customer's ZIP is missing, not in the database, or the order is international. The order activity log shows the specific reason.

Does this affect existing orders?
Yes. Turning geo-routing on for a store routes every open (unstarted) order for that store in the background. Turning it off clears auto-routed assignments β€” manual overrides are preserved.

Is there still an account-wide on/off switch?
No. Geo-routing is configured per store from Settings β†’ Inventory β†’ Geo Route. Each store has its own toggle, warehouse list, priority setting, and Disable Split Geo Routing toggle.

What does "Disable Split Geo Routing" do?
When on for a store, geo-routing assigns the entire order to a single warehouse β€” the closest one that can fulfill every item. If no single warehouse can cover the order, it falls back to the closest warehouse that can fulfill the most items and tags the order "Failed Geo-Routing". Use this when split shipments aren't acceptable.

How do I let one order split when the store has Disable Split Geo Routing turned on?
Create a shipping rule with the Apply Geo Route for Order action and a filter that matches the order (e.g., order tag force_split).

Why is a rule showing "Conflicting with: <other rule>"?
Two active rules would route the same kind of order to different outcomes. The rules table flags both rows so you can decide which one wins. Identical rules are treated as redundant and not flagged.

What if I only have one warehouse?
Geo-routing runs but all items go to that warehouse. No real benefit β€” leave it off.

Can I manually override a warehouse assignment?
Yes. From the picking interface, reassign a whole section, an individual item, or a partial quantity. Manual assignments stick across re-routes (unless someone forces a re-route).

Does this work with international orders?
No. Only US ZIPs are supported. International orders are flagged with non_us_address and skip routing.

How does this interact with warehouse-linked reserves?
Geo-routing reads the "free" quantity (on-hand minus reserves) per warehouse to decide where stock is actually available. This avoids over-promising stock that's already committed to another order.

What happens if my closest warehouse runs out mid-day?
The next order routes to the next-closest warehouse with stock. Geo-routing does not re-route already-routed open orders when stock changes.

Can I exclude a warehouse from a specific channel?
Yes β€” via warehouse links. Remove the warehouse from a store/location's linked-warehouse list and routing skips it for that channel.

Can a single order ship from multiple warehouses?
Yes β€” that's the normal split fulfillment behavior. The picking UI groups items by warehouse so each location only handles its own pieces.


Known limitations

  • US ZIPs only. International postal codes aren't supported.

  • No automatic re-routing on stock changes. Routing runs at sync time, on warehouse-link changes, and on manual re-route.

  • ZIP database covers ~42,500 codes β€” very new or unusual codes may be missing. The database refreshes monthly; support can trigger an immediate refresh if needed.

  • Shopify per-location inventory mismatch during reassignment: when a user manually moves an item from one warehouse to another, SKULabs doesn't call Shopify's fulfillmentOrderMove API. Per-location Shopify counts can temporarily differ until the next stock sync. Total inventory is always correct β€” only per-location counts can drift briefly.

Did this answer your question?