Back to arkyStore.io

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.

List Locations

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

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

Get Location

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

Parameters

Name Type Description
id required string Location ID

Create Location

POST /v1/stores/{storeId}/locations
SDK: sdk.location.create()
const location = await sdk.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 profiles can pick up orders here

Update Location

PUT /v1/stores/{storeId}/locations/{id}
SDK: sdk.location.update()
await sdk.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 profiles can pick up orders here

Delete Location

DELETE /v1/stores/{storeId}/locations/{id}
SDK: sdk.location.delete()
await sdk.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.market.update(). See the Market API reference.

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

await sdk.market.update({
  id: us.id,
  zones: [
    {
      market_id: us.id,
      store_id: us.storeId,
      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.location.getCountries()

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

const result = await sdk.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.location.getCountry()

Get a single country along with its states/provinces.

const country = await sdk.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.location.getCountries().then(res => setCountries(res.items));
  }, []);

  // Load states when country changes
  useEffect(() => {
    if (!selectedCountry) {
      setStates([]);
      return;
    }
    sdk.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.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.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.market.update() with a tax_bps and shipping_methods per region, then let checkout match the profile’s address against your zones automatically.