Back to Arky

Location

Store locations, zones, and country/state reference data

The Location module covers three things:

  1. Store locations — physical stores, warehouses, and pickup points attached to a store.
  2. Zones — geographic regions that define tax, payment, and shipping behavior for orders.
  3. Platform reference data — the list of countries and states used by address forms everywhere.

Store Locations

A store location is a physical place (store, warehouse, pickup point) owned by a store. Locations are referenced by inventory levels and can be marked as pickup-eligible. A new store’s default location is intentionally unconfigured; update it with a real postal address and an explicit ISO country code before using it for shipping or pickup. Arky does not infer US or any other country.

List Locations

GET /v1/stores/{storeId}/locations
SDK: sdk.store.location.list()
const locations = await sdk.store.location.list();

locations.forEach((location) => {
	console.log(location.key, location.address.city);
});

Get Location

GET /v1/stores/{storeId}/locations/{id}
SDK: sdk.store.location.get()
const location = await sdk.store.location.get("loc_abc123");

Parameters

Name Type Description
id required string Location ID

Create Location

POST /v1/stores/{storeId}/locations
SDK: sdk.store.location.create()
const location = await sdk.store.location.create({
	key: "main-store",
	address: {
		name: "Main Store",
		street1: "123 Market St",
		city: "New York",
		state: "NY",
		postal_code: "10001",
		country: "US",
	},
	is_pickup_location: true,
});

Parameters

Name Type Description
key required string Unique location key
address required Address Full postal address
is_pickup_location optional boolean Whether contacts can pick up orders here

Update Location

PUT /v1/stores/{storeId}/locations/{id}
SDK: sdk.store.location.update()
await sdk.store.location.update({
	id: "loc_abc123",
	key: "main-store",
	address: {
		name: "Main Store",
		street1: "500 Broadway",
		city: "New York",
		state: "NY",
		postal_code: "10012",
		country: "US",
	},
	is_pickup_location: true,
});

Parameters

Name Type Description
id required string Location ID to update
key required string Unique location key
address required Address Full postal address
is_pickup_location optional boolean Whether contacts can pick up orders here

Delete Location

DELETE /v1/stores/{storeId}/locations/{id}
SDK: sdk.store.location.delete()
await sdk.store.location.delete({ id: "loc_abc123" });

Zones

Zones define geographic regions (by country, state, or postal code) and their associated tax rate and shipping methods. Zones are embedded in a market (Market.zones[]) and apply to order quote and checkout flows. Service appointment lines can be quoted without shipping, while product lines need a shipping address or a matching order zone when zone-based tax or shipping applies. Payment methods live on the Market, not the zone.

Zones have no standalone endpoints — add, edit, or remove them by passing a full zones array to sdk.store.market.update(). See the Market API reference.

const markets = await sdk.store.market.list();
const us = markets.find((m) => m.key === "us")!;

await sdk.store.market.update({
	id: us.id,
	zones: [
		{
			countries: ["US"],
			states: ["NY", "NJ"],
			postal_codes: [],
			tax_bps: 825,
			shipping_methods: [
				{ id: "sm_standard", taxable: true, eta_text: "3-5 days", amount: 599 },
			],
		},
	],
});

Platform Reference Data

Read-only lists of countries and their states/provinces. Useful for populating address forms.

Get Countries

GET /v1/platform/countries
SDK: sdk.store.location.getCountries()

Retrieve the paginated list of countries (each entry includes its states).

const result = await sdk.store.location.getCountries();

result.items.forEach(country => {
console.log(country.code, country.name, country.states.length);
// US, United States, 50
// CA, Canada, 13
// ...
});

Response

interface GetCountriesResponse {
	items: LocationCountry[];
	cursor: string | null;
}

interface LocationCountry {
	code: string; // ISO 3166-1 alpha-2 code
	name: string; // Full country name
	states: LocationState[]; // States/provinces
}

interface LocationState {
	code: string; // State/province code
	name: string; // Full name
}

Get Country

GET /v1/platform/countries/{countryCode}
SDK: sdk.store.location.getCountry()

Get a single country along with its states/provinces.

const country = await sdk.store.location.getCountry("US");

country.states.forEach((state) => {
	console.log(state.code, state.name);
	// AL, Alabama
	// AK, Alaska
	// AZ, Arizona
	// ...
});

Parameters

Name Type Description
countryCode required string ISO 3166-1 alpha-2 country code

Use Cases

Address Form

import { useState, useEffect } from 'react';
import type { LocationCountry, LocationState } from 'arky-sdk';

function AddressForm() {
  const [countries, setCountries] = useState<LocationCountry[]>([]);
  const [states, setStates] = useState<LocationState[]>([]);
  const [selectedCountry, setSelectedCountry] = useState('');

  // Load countries on mount
  useEffect(() => {
    sdk.store.location.getCountries().then(res => setCountries(res.items));
  }, []);

  // Load states when country changes
  useEffect(() => {
    if (!selectedCountry) {
      setStates([]);
      return;
    }
    sdk.store.location.getCountry(selectedCountry).then(country => {
      setStates(country.states);
    });
  }, [selectedCountry]);

  return (
    <form>
      <select
        value={selectedCountry}
        onChange={(e) => setSelectedCountry(e.target.value)}
      >
        <option value="">Select Country</option>
        {countries.map(country => (
          <option key={country.code} value={country.code}>
            {country.name}
          </option>
        ))}
      </select>

      <select disabled={!selectedCountry}>
        <option value="">Select State</option>
        {states.map(state => (
          <option key={state.code} value={state.code}>
            {state.name}
          </option>
        ))}
      </select>
    </form>
  );
}

Caching

Since country/state data rarely changes, cache it on the client:

import type { LocationCountry } from "arky-sdk";

let countriesCache: LocationCountry[] | null = null;
const countryCache = new Map<string, LocationCountry>();

async function getCountries(): Promise<LocationCountry[]> {
	if (countriesCache) return countriesCache;
	const res = await sdk.store.location.getCountries();
	countriesCache = res.items;
	return countriesCache;
}

async function getCountry(countryCode: string): Promise<LocationCountry> {
	if (countryCache.has(countryCode)) {
		return countryCache.get(countryCode)!;
	}
	const country = await sdk.store.location.getCountry(countryCode);
	countryCache.set(countryCode, country);
	return country;
}
Tip

Zones, not country reference data, control tax and shipping rules. Pass zones inline on sdk.store.market.update() with a tax_bps and shipping_methods per region, then let checkout match the contact’s address against your zones automatically.