This is not the same thing as the npm Packages covered elsewhere on this site. Those embed the geographical data directly — no API key, no network call.
@countrystatecity/sdk is the opposite: a live REST API client. It needs an API key, makes real HTTP requests, and is subject to your plan’s usage quotas — in exchange, it’s always current and covers endpoints the offline packages don’t have (search, usage, and live currency/timezone/phone lookups). You can use both together — see Migrating from the local packages below.Installation
fetch) or any modern browser. Zero runtime dependencies — built entirely on native fetch, URL/URLSearchParams, and AbortController. You’ll need an API key — get one free and compare plans and quotas.
Quick Start
{ data, meta } — data contains the typed result and meta carries request, usage, pagination, and cache information alongside it. See Response Metadata below.
Configuration
The SDK never reads
apiKey from an environment variable and never writes it to disk — pass it explicitly at construction time.Resource Reference
Everylist/get/etc. method also accepts a trailing { signal?, timeout?, headers? } for per-call overrides — see Retries & Timeouts below.
csc.cities.list({ state }) requires country to also be set — a ValidationError is thrown client-side otherwise, before any network call.Error Handling
All errors extendCSCError (message, statusCode, requestId, url, retryCount):
Error class reference
ValidationError can also be thrown synchronously — as a rejected promise, before any network call is made — for malformed input like bad ISO codes, out-of-range coordinates, or invalid limits.
Retries & Timeouts
GET requests are retried automatically on transient network errors,429, and 5xx responses — never on 401/403/404/400-class responses, and never on a caller-initiated AbortSignal cancellation. Defaults: 2 retries, full-jitter exponential backoff (200ms base, 2000ms cap). Any Retry-After response header takes precedence over the computed delay.
Response Metadata
csc.getLastResponseMeta() returns the metadata from the most recent successful request on that client instance — useful for surfacing usage in a UI without an extra call.
Browser Usage
Node.js and Next.js
Use the SDK directly in any Node.js 18+ script or backend service. In Next.js, keep it server-side — in a Route Handler, Server Component, or Server Action — so your API key never reaches the client bundle.Bundle Size
~6.9KB gzipped (ESM build), against a 20KB budget enforced in CI — zero runtime dependencies.Migrating from the Local Packages
If you’re already using@countrystatecity/countries and want live, quota-aware data instead of the weekly-updated bundled snapshot:
Why migrate
- You need data more current than the weekly-updated local snapshot.
- You need
searchorusage— neither has a local-package equivalent. - You’re already calling the live API elsewhere and want one typed client instead of hand-rolled
fetchcalls.
Why not to migrate
If you don’t need any of the above, staying on the local package is usually the better choice — it’s free, has no network latency, and isn’t subject to plan quotas.What changes
- An API key is required. The local package needs none.
- Every call is async and can fail with a network-shaped error (
RateLimitError,NetworkError,TimeoutError, and others) in addition to the local package’s simpler failure modes. - Results are quota-limited per your plan (
RateLimitError), not just rate-limited by your own code. - The shape is
{ data, meta }, not the bare array/object the local package returns — destructuredataat the call site.
TypeScript Types
Source
GitHub Repository
View the SDK source, open issues, or contribute.
npm Package
View published versions and changelog.