Warehouses, Stock, and Shipping
This guide provides instructions on how to set up warehouses, shipping zones and rates, and assign stock (inventory) to product variants using the GraphQL API.
In Nautical, warehouses, shipping zones, and shipping rates need to be created before buyers can order products. This can be done by the marketplace operator or sellers who have necessary permissions. The marketplace operator can see all warehouses, while sellers can only see and assign inventory to their own warehouses and the marketplace operator's warehouses.
Warehouses: A warehouse represents the physical location where inventory for one or more product variants is stored.
Shipping zones: A shipping zone is assigned to a warehouse and determines the countries to which product variants from that warehouse can be shipped. A warehouse can have multiple shipping zones.
Shipping rates: Shipping rates, also known as shipping methods, are associated with shipping zones and determine the cost of shipping based on the weight or price of the seller order.
To enable functionalities such as creating stock for product variants, assigning stock to specific warehouses, and providing available shipping rates to buyers based on their address, it is important to establish the correct connections between warehouses, shipping zones, and shipping rates.
Create a Warehouseβ
In order to create a warehouse, you would use the createWarehouse
mutation, as so:
mutation {
createWarehouse(
input: {
addShippingZones: []
address: {
city: "New York"
country: US
countryArea: "NY"
phone: "+12125439876"
postalCode: "10000"
streetAddress1: "123 Main St"
streetAddress2: "Suite 1A"
}
name: "Warehouse New York City"
seller: "U2VsbGVyOjE="
}
) {
warehouse {
id
name
}
warehouseErrors {
field
message
code
}
}
}
One of the items returned in the response to the above is the Warehouse ID. You'll need this ID for warehouse updates in the Attaching Shipping Zone to Warehouse section. You could always query warehouses if you accidentally lose sight of this ID.
For the input.seller
field, if you're the Marketplace Operator, you can enter the Seller ID of any Seller into that field. If you created it under yourself as the Marketplace Operator (the special case where Seller ID is 1), any and all Sellers will be able to see and create inventory against that Warehouse. If you create it for another Seller, only you and that Seller will be able to see that Warehouse. Sellers can only see the Marketplace Operator's and their own Warehouses.
Sellers Queryβ
To view all Seller info as a Marketplace Operator in order to grab the Seller ID of interest for use in the mutation above, you can use the sellers query, as so:
{
sellers(first: 100) {
edges {
node {
id
companyName
}
}
}
}
Me Queryβ
Otherwise, if you're a Seller and need to grab your own Seller ID for use in the mutation above (or if you're the Marketplace Operator and only care to grab your own Seller ID), you can use the me query, as so:
{
me {
seller {
id
companyName
}
}
}
Creating a Shipping Zoneβ
In order to create a Shipping Zone, you would use the shippingZoneCreate
mutation, as so:
shippingZoneCreate(
input: {
addWarehouses: []
countries: ["CA", "US"]
default: false
name: "Shipping Zone US & Canada"
seller: "U2VsbGVyOjE="
}
) {
shippingZone {
id
name
}
shippingErrors {
field
message
code
}
}
}
One of the items returned in the response to the above is the Shipping Zone ID. You'll need this ID for shipping zone updates in the Attaching Shipping Zone to Warehouse section. You could always query shippingZones if you accidentally lose sight of this ID.
For the input.seller
field, if you're the Marketplace Operator, you can enter the Seller ID of any Seller into that field. If you created it under yourself as the Marketplace Operator (the special case where Seller ID is 1), any and all Sellers will be able to see and use that Shipping Zone. If you create it for another Seller, only you and that Seller will be able to see that Shipping Zone. Sellers can only see the Marketplace Operator's and their own Shipping Zones.
Sellers Queryβ
To view all Seller info as a Marketplace Operator in order to grab the Seller ID of interest for use in the mutation above, you can use the sellers query, as so:
{
sellers(first: 100) {
edges {
node {
id
companyName
}
}
}
}
Me Queryβ
Otherwise, if you're a Seller and need to grab your own Seller ID for use in the mutation above (or if you're the Marketplace Operator and only care to grab your own Seller ID), you can use the me query, as so:
{
me {
seller {
id
companyName
}
}
}
Associate Shipping Zone with Warehouseβ
You can attach a Shipping Zone to a Warehouse via either the updateWarehouse
mutation or the shippingZoneUpdate
mutation. We'll look at updateWarehouse
first.
Attach Warehouse to a Shipping Zoneβ
You can attach a Shipping Zone to a Warehouse via the updateWarehouse
mutation. You'll need the ID of the Warehouse you wish to attach the Shipping Zone to, which you can get from your prior executed createWarehouse
mutation, or by finding it via the warehouses
query. You'll also need the Shipping Zone ID for the Shipping Zone you wish to connect to the Warehouse. You can get this from your prior executed shippingZoneCreate
mutation, or by finding it via the shippingZones
query.
Getting these IDs, we can run the updateWarehouse
mutation, as so:
mutation {
updateWarehouse(
id: "V2FyZWhvdXNlOjc5YzI5YTVmLTVlNzEtNGU0Ni1iMjQzLWYwOTY0YjI3MjA1NQ=="
input: { addShippingZones: ["U2hpcHBpbmdab25lOjEw"] }
) {
warehouse {
id
name
shippingZones(first: 10) {
edges {
node {
id
name
}
}
}
}
}
}
This connects the Shipping Zone to the warehouse. You can attach many Shipping Zones to many Warehouses.
Attach Shipping Zone to Warehouseβ
Alternatively, you can attach a Shipping Zone to a Warehouse via the shippingZoneUpdate
mutation. You'll need the ID of the Shipping Zone you wish to attach to the Warehouse, which you can get from your prior executed shippingZoneCreate
mutation, or by finding it via the shippingZones query. You'll also need the Warehouse ID for the Warehouse you wish to connect the Shipping Zone to. You can get this from your prior executed createWarehouse
mutation, or by finding it via the warehouses
query.
Getting these IDs, we can run the shippingZoneUpdate
mutation, as so:
mutation {
shippingZoneUpdate(
id: "U2hpcHBpbmdab25lOjEw"
input: {
addWarehouses: [
"V2FyZWhvdXNlOjc5YzI5YTVmLTVlNzEtNGU0Ni1iMjQzLWYwOTY0YjI3MjA1NQ=="
]
}
) {
shippingZone {
id
warehouses {
id
name
}
}
shippingErrors {
field
message
code
}
}
}
This connects the Shipping Zone to the Warehouse. You can attach many Shipping Zones to many Warehouses.
Creating Shipping Rates/Methodsβ
We now have a Warehouse and a Shipping Zone attached to it. This allows us to assign Product Variant inventory to the Warehouse and lets us know what countries this Warehouse is able to ship these items to.
Now the question is, what is the Shipping Method Name and associated cost if, say, 3 of these Product Variants are being shipped to a country in the Shipping Zone? What if instead 25 of these Product Variants are being shipped?
We'd expect the cost to be greater (or different, at least) for shipments of MORE stuff compared to LESS stuff. To accommodate this reality, we allow the creation of Shipping Rates/Methods by Seller Order total weight and/or by Seller Order total price.
Creating Price-Based Shipping Rates/Methodsβ
For a Shipping Zone, we can create Shipping Rates/Methods for Seller Orders of various total price. For example, for a given Shipping Zone, for shipments totaling $0 - 25, we may want to charge $5 in shipping and call that Shipping Rate/Method βStandardβ or βUPSβ or whatever. And we can set a different rate for Seller Orders above $25. And so on.
That being said, with the ID of the Shipping Zone you wish to create a Shipping Rate/Method for in hand, we can create a price-based Shipping Rate/Method using the shippingPriceCreate
mutation, as so:
mutation {
shippingPriceCreate(
input: {
maximumOrderPrice: 99
minimumOrderPrice: 0
name: "Standard"
price: 2.5
shippingZone: "U2hpcHBpbmdab25lOjEw"
type: PRICE
}
) {
shippingZone {
id
name
}
shippingMethod {
id
name
}
shippingErrors {
field
message
code
}
}
}
Creating Weight-Based Shipping Rates/Methodsβ
For a Shipping Zone, we can create Shipping Rates/Methods for Seller Orders of various total weight. For example, for a given Shipping Zone, for shipments totaling 0 - 5kg, we may want to charge $5 in shipping and call that Shipping Rate/Method βStandardβ or βUPSβ or whatever. And we can set a different rate for Seller Orders above 5kg. And so on.
That being said, with the ID of the Shipping Zone you wish to create a Shipping Rate/Method for in hand, we can create a weight-based Shipping Rate/Method using the shippingPriceCreate
mutation, as so:
mutation {
shippingPriceCreate(
input: {
maximumOrderWeight: 5
minimumOrderWeight: 0
name: "5-Day"
price: 7.25
shippingZone: "U2hpcHBpbmdab25lOjEw"
type: WEIGHT
}
) {
shippingZone {
id
name
}
shippingMethod {
id
name
}
shippingErrors {
field
message
code
}
}
}
You can create many such weight-based Shipping Rates/Methods for the given Shipping Zone.
Assigning Product Variant Inventory to a Warehouseβ
We've gone ahead and set up everything we need to now be able to assign Product Variant Inventory to a Warehouse.
To assign Product Variant inventory/stock to a Warehouse, we can use the productVariantStocksCreate
mutation, as so:
mutation {
productVariantStocksCreate(
stocks: [
{
quantity: 100
warehouse: "V2FyZWhvdXNlOjc5YzI5YTVmLTVlNzEtNGU0Ni1iMjQzLWYwOTY0YjI3MjA1NQ=="
}
]
variantId: "UHJvZHVjdFZhcmlhbnQ6MTk1"
) {
productVariant {
id
name
product {
id
name
}
stocks {
quantity
quantityAllocated
}
}
bulkStockErrors {
field
message
code
}
}
}
As implied in the above, you'll need the ID(s) of the Warehouse(s) you plan to assign Product Variant inventory/stock to, and you'll need the Product Variant ID. These can be grabbed from the warehouses
and productVariants
queries.
That's it. That's how to set Up Warehouses, Shipping Zones, and Shipping Rates/Methods and Assign Stock/Inventory to Product Variants.