Skip to content

Country States ​

A country state is any sub-division of a country — state, province, territory, prefecture, etc. Each state belongs to exactly one country and identifies itself with a short code (AL, CA, BC, MH, …).

Endpoints ​

The same resource is exposed under two URL shapes so clients can choose the access pattern that fits their UI:

MethodPathPurpose
GET/api/shop/countries/{country_id}/statesNested — every state for a single country (recommended for cascade pickers)
GET/api/shop/countries/{country_id}/states/{id}Nested — single state, scoped to its parent country
GET/api/shop/country-statesFlat — every state across every country in one paginated stream
GET/api/shop/country-states/{id}Flat — single state by global ID

Two things hold across all four:

  • The response shape is identical — only the URL and its scoping differ. Use the example switcher above the curl block to flip through them.
  • State IDs come from one global sequence, so id: 66 is Alberta whether you reach it through /countries/40/states/66 or /country-states/66.

When to use which ​

ScenarioEndpoint
Country/state cascade dropdown in a checkout formGET /api/shop/countries/{country_id}/states
Resolve a single state ID (e.g. stored on an order address)GET /api/shop/country-states/{id}
Build an offline cache of every state in the worldGET /api/shop/country-states (paginate through)
Validate that a state belongs to a specific countryGET /api/shop/countries/{country_id}/states/{id} (404 if mismatched)

Request Headers ​

HeaderRequiredDescription
AcceptYesapplication/json
X-STOREFRONT-KEYYesStorefront API key (pk_storefront_…)

Query Parameters (collections only) ​

ParameterTypeDefaultDescription
pageinteger1Page number (1-based)
per_pageinteger10Items per page. Max 50.

Pagination headers (X-Total-Count, X-Page, X-Per-Page, X-Total-Pages) are emitted on both collection variants. See Pagination.

State Object Fields ​

FieldTypeDescription
idintegerState primary key (globally unique across countries)
countryIdintegerOwning country ID
countryCodestringISO country code of the parent (CA, US, …)
codestringState/province code within the country (AB, CA, MH, …)
defaultNamestringDefault English name
translationsarray of path referencesOne reference per locale. Fetch GET /api/shop/country_state_translations/{id} to read one. Countries inline their translations, but states do not — keeping the flat 586-row collection lean. See IRIs & HATEOAS.

Use Cases ​

  • Render a state/province dropdown that depends on the chosen country (use the nested collection).
  • Validate a state_id saved on an order against its country_id (use the nested single — 404 means mismatched).
  • Resolve a localized state name for a given customer locale by following one of the translations[] IRIs.
  • Bulk-export every state for a CSV / SPA cache (use the flat collection with ?per_page=50).

Best Practices ​

  • Prefer the nested route for a picker — /api/shop/countries/{countryId}/states returns just that country's states, while this flat collection pages through every state in the world.
  • Match on code, not on the display name — checkout stores the state code, and names change with the request locale.
  • Cache alongside the country list — the data is static reference data.

Released under the MIT License.