Store Locations
The store's places, where pickups happen and deliveries leave from, and country reference data
A store location is one of the store’s places: a shop, a warehouse or a studio. Deliveries leave from its address, pickups happen there, and its timezone sets its business days. Every store starts with one default location.
import type { EpochMilliseconds } from "arky-sdk";
interface StoreLocation {
id: string;
store_id: string;
key: string;
address: PostalAddress;
timezone: string;
blocks: Block[];
status: { type: "active" } | { type: "archived" } | { type: "deleting" };
created_at: EpochMilliseconds;
updated_at: EpochMilliseconds;
}
blocks hold its name, opening hours and pickup instructions per language.
Store Locations
/v1/stores/{store_id}/locations sdk.store.location.create() /v1/stores/{store_id}/locations sdk.store.location.find() /v1/stores/{store_id}/locations/{id} sdk.store.location.get() /v1/stores/{store_id}/locations/by-key/{key} sdk.store.location.getByKey() /v1/stores/{store_id}/locations/{id} sdk.store.location.update() /v1/stores/{store_id}/locations/{id}?expected_updated_at= sdk.store.location.delete() const shop = await sdk.store.location.create({
store_id: storeId,
id: crypto.randomUUID(),
key: "berlin-center",
address: { street1: "Hauptstraße 1", city: "Berlin", postal_code: "10115", country: "DE" },
timezone: "Europe/Berlin",
blocks: [
{ id: crypto.randomUUID(), key: "name", type: "localized_text", value: { en: "Berlin Center", de: "Berlin Mitte" } },
],
});Parameters
| Name | Type | Description |
|---|---|---|
id required | string | The location id the app picks (UUID v4) |
key required | string | The location's name, unique in the store (409 STORE_LOCATION.KEY_TAKEN otherwise) |
address optional | PostalAddressInput | Where deliveries leave from and pickups happen |
timezone required | string | An IANA timezone, such as Europe/Berlin |
blocks optional | Block[] | Name, hours and pickup instructions per language |
- Pickup points. A location offers pickup exactly when an active pickup shipping method names it. To stop pickup there, archive the method.
- Archiving closes a location and keeps its history (stock movements, past shipments). It is refused while a role’s reach, a company location’s fulfillment, the routing record or an open job points at it.
- Deleting marks the location
deletingand cleans up after it; it is refused while anything points at it or any stock level there still counts on-hand, reserved or unavailable units. - Updates and deletes carry the
expected_updated_atthey read.
Storefront
const locations = await arky.store.location.find({ limit: 50 });
const pickupPoints = locations.items.filter((location) => location.pickup_point);
for (const location of pickupPoints) {
console.log(location.key, location.address.city);
}
The storefront copy is { id, key, address, pickup_point }. The list takes key, sort_field
(created_at or updated_at), sort_direction, limit and cursor; filter pickup points by
their pickup_point flag.
Platform Reference Data
Read-only lists of countries and their states/provinces. Useful for populating address forms.
Get Countries
/v1/platform/countries sdk.store.country.find() Retrieve the paginated list of countries (each entry includes its states).
const result = await sdk.store.country.find();
result.items.forEach(country => {
console.log(country.code, country.name, country.states.length);
// US, United States, 50
// CA, Canada, 13
// ...
});Response
type Countries = PaginatedResponse<LocationCountry>;
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
/v1/platform/countries/{code} sdk.store.country.get() Get a single country along with its states/provinces.
const country = await sdk.store.country.get({ code: "US" });
country.states.forEach((state) => {
console.log(state.code, state.name);
// AL, Alabama
// AK, Alaska
// AZ, Arizona
// ...
});Parameters
| Name | Type | Description |
|---|---|---|
code 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.country.find().then(res => setCountries(res.items));
}, []);
// Load states when country changes
useEffect(() => {
if (!selectedCountry) {
setStates([]);
return;
}
sdk.store.country.get({ code: 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.country.find();
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.country.get({ code: countryCode });
countryCache.set(countryCode, country);
return country;
}Zones, not country reference data, control tax and shipping. Each zone belongs to one market, and tax rules and shipping rates name zones; the quote matches the customer’s address against the market’s zones. See Markets and Channels.