Back to arky.io

Location

Business locations, zones, and country/state reference data

The Location module covers three things:

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

Business Locations

A business location is a physical place (store, warehouse, pickup point) owned by a business. Locations are referenced by inventory levels and can be marked as pickup-eligible.

List Locations

GET /v1/businesses/{businessId}/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/businesses/{businessId}/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/businesses/{businessId}/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',
    postalCode: '10001',
    country: 'US'
  },
  isPickupLocation: true
});

Parameters

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

Update Location

PUT /v1/businesses/{businessId}/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',
    postalCode: '10012',
    country: 'US'
  },
  isPickupLocation: true
});

Parameters

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

Delete Location

DELETE /v1/businesses/{businessId}/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 flows only. Booking flows never consult zones. 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: [
    {
      marketId: us.id,
      businessId: us.businessId,
      countries: ['US'],
      states: ['NY', 'NJ'],
      postalCodes: [],
      taxBps: 825,
      shippingMethods: [
        { id: 'sm_standard', taxable: true, etaText: '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 taxBps and shippingMethods per region, then let checkout match the customer’s address against your zones automatically.