Skip to main content

Getting Started

The process is simple:
  1. Visit app.countrystatecity.in
  2. Sign up or log in to your account
  3. Create your API key instantly
You can make your first API call within minutes:
curl -X GET 'https://api.countrystatecity.in/v1/countries' \
  -H 'X-CSCAPI-KEY: YOUR_API_KEY'
Your API key is ready to use immediately after registration - no waiting period required.
While we don’t maintain official SDKs, our RESTful API works with any programming language that can make HTTP requests. We provide comprehensive integration examples for:
  • JavaScript/Node.js
  • Python
  • PHP
  • Java
  • C#
  • Go
  • Ruby
Community members have also created unofficial libraries for various platforms.

Authentication & Security

Authentication is done using API key headers. Include your API key in every request:
X-CSCAPI-KEY: YOUR_API_KEY
const response = await fetch('https://api.countrystatecity.in/v1/countries', {
  headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' }
});
Never expose your API key in client-side code such as browser JavaScript, mobile apps, or public repositories.
Safe practices:
  • Use server-side applications or serverless functions
  • Store API keys in environment variables
  • Implement your own backend API that securely calls our API
  • Use build-time environment variables for static sites
Why this matters:
  • API keys in client-side code are visible to anyone
  • Malicious users could extract and abuse your API key
  • This could lead to unexpected usage and charges
Yes! You can manage your API keys through the developer portal:
  1. Log into your account
  2. Navigate to API key management
  3. Generate a new key
  4. Update your applications with the new key
  5. Revoke the old key once migration is complete
Keep both keys active during migration to avoid service interruption.
A 401 error typically indicates an authentication issue:Common causes and solutions:
  • Invalid API key: Double-check your API key for typos
  • Wrong header name: Ensure you’re using X-CSCAPI-KEY exactly
  • Missing header: Verify the header is being sent with every request
  • Expired/revoked key: Generate a new API key if needed
Test your authentication:
curl -X GET 'https://api.countrystatecity.in/v1/countries' \
  -H 'X-CSCAPI-KEY: YOUR_API_KEY' \
  -w "HTTP Status: %{http_code}\n"
A successful test returns HTTP 200 with country data.
When you exceed your rate limit, you’ll receive a 429 Too Many Requests response:
{
  "error": "Rate limit exceeded",
  "message": "Too many requests. Please try again later.",
  "retry_after": 3600
}
Best practices for handling rate limits:
  • Implement exponential backoff retry logic
  • Cache responses to reduce API calls
  • Monitor usage proactively
  • Consider upgrading your plan if limits are consistently hit — plans start at $5/month for higher limits. Visit https://app.countrystatecity.in/pricing to compare plans.
The Retry-After header indicates how long to wait before making another request.
Effective caching strategies:
  • Cache country/state data for 24+ hours (rarely changes)
  • Cache city data for 12+ hours
  • Implement local fallbacks for critical data
Efficient request patterns:
  • Fetch broader datasets when possible (all countries vs individual requests)
  • Use hierarchical endpoints strategically
  • Batch related requests together
Example caching implementation:
class APICache {
  constructor(ttl = 24 * 60 * 60 * 1000) {
    this.cache = new Map();
    this.ttl = ttl;
  }

  get(key) {
    const item = this.cache.get(key);
    if (!item || Date.now() - item.timestamp > this.ttl) {
      return null;
    }
    return item.data;
  }

  set(key, data) {
    this.cache.set(key, { data, timestamp: Date.now() });
  }
}

Data & Endpoints

Countries include:
  • ISO2 and ISO3 codes
  • Country name and native name
  • Phone code and currency information
  • Flag emoji and region information
  • Latitude and longitude coordinates
States include:
  • State name and ISO2 code
  • Country association
  • State type (state, province, region, etc.)
  • Latitude and longitude coordinates
Cities include:
  • City name and unique ID
  • Country and state association
  • Latitude and longitude coordinates
  • Timezone information (when available)
Use the detailed endpoints (/countries/{iso2}) to get complete information including additional metadata.
Our data is continuously maintained and updated:
  • Country data: Updated as needed for political changes, currency updates, etc.
  • State/Province data: Updated for administrative boundary changes
  • City data: Regular additions and corrections based on authoritative sources
We implement automated validation and quality checks to ensure data accuracy. Major updates are announced through our changelog.
The dataset includes 247+ countries, 5,000+ states/provinces, and 151,000+ cities worldwide.
No, for performance and efficiency reasons, our API is designed with hierarchical endpoints:
  • /countries - All countries
  • /countries/{countryCode}/states - States within a country
  • /countries/{countryCode}/cities - Cities within a country
  • /countries/{countryCode}/states/{stateCode}/cities - Cities within a state
Why this design:
  • Faster response times for specific data
  • Reduced bandwidth usage
  • Better caching opportunities
  • More manageable response sizes
Requesting all cities globally would result in 151,000+ records, which would be slow and consume significant bandwidth.
Yes! Latitude and longitude coordinates are included for:
  • Countries: Approximate center coordinates
  • States/Provinces: Administrative center coordinates
  • Cities: City center coordinates
Example city response:
{
  "id": 12345,
  "name": "Los Angeles",
  "latitude": "34.05223",
  "longitude": "-118.24368",
  "country_code": "US",
  "state_code": "CA"
}
Coordinates are provided as strings for precision and can be easily converted to numbers for calculations.
Yes, we follow international standards:Country Codes:
  • ISO 3166-1 alpha-2 (2-letter codes like “US”, “GB”)
  • ISO 3166-1 alpha-3 (3-letter codes like “USA”, “GBR”)
Currency Codes:
  • ISO 4217 standard (3-letter codes like “USD”, “EUR”)
Phone Codes:
  • ITU-T E.164 standard international calling codes
This ensures compatibility with other international systems and databases.

Integration & Development

We strongly recommend against making direct API calls from browser applications due to security concerns with exposing API keys.
Recommended approaches:
  1. Server-side proxy: Create your own API endpoint that calls our API
  2. Serverless functions: Use services like Vercel Functions, Netlify Functions, or AWS Lambda
  3. Static site generation: Fetch data at build time for static sites
Why avoid direct browser calls:
  • API keys are visible in browser developer tools
  • Risk of key theft and unauthorized usage
  • Potential CORS restrictions
Implement cascading dropdowns by chaining API calls based on user selections:React example pattern:
const [selectedCountry, setSelectedCountry] = useState('');
const [states, setStates] = useState([]);
const [cities, setCities] = useState([]);

// Load states when country changes
useEffect(() => {
  if (selectedCountry) {
    loadStates(selectedCountry);
    setCities([]); // Clear cities when country changes
  }
}, [selectedCountry]);

const loadStates = async (countryCode) => {
  const statesData = await api.getStates(countryCode);
  setStates(statesData);
};

Complete Example

See our comprehensive cascading dropdown implementation guide
Implement comprehensive error handling for different scenarios:Error types and handling:
async function makeAPIRequest(endpoint) {
  try {
    const response = await fetch(endpoint, { headers });

    if (response.status === 401) {
      throw new Error('INVALID_API_KEY');
    } else if (response.status === 404) {
      throw new Error('NOT_FOUND');
    } else if (!response.ok) {
      throw new Error('API_ERROR');
    }

    return await response.json();

  } catch (error) {
    if (error.message === 'INVALID_API_KEY') {
      // Notify user to check API configuration
      console.error('Invalid API key configuration');
    }
    throw error;
  }
}
Best practices:
  • Always check response status codes
  • Implement retry logic for temporary failures
  • Provide meaningful error messages to users
  • Log errors for debugging purposes
Yes, caching is highly recommended and beneficial:Recommended cache durations:
  • Countries: 24-48 hours (very stable data)
  • States: 12-24 hours (occasionally updated)
  • Cities: 6-12 hours (more frequently updated)
Implementation strategies:
// Browser localStorage
const cacheKey = 'countries_data';
const cachedData = localStorage.getItem(cacheKey);
const isExpired = Date.now() - cachedData?.timestamp > 24 * 60 * 60 * 1000;

if (cachedData && !isExpired) {
  return JSON.parse(cachedData).data;
}

// Server-side caching (Redis, Memcached, etc.)
const redis = require('redis');
const client = redis.createClient();

const cached = await client.get('countries');
if (cached) return JSON.parse(cached);

const data = await fetchFromAPI();
await client.setex('countries', 86400, JSON.stringify(data)); // 24h TTL
Caching reduces API usage, improves performance, and provides offline fallbacks.

Troubleshooting

This can happen for several reasons:Common causes:
  1. Incorrect country/state codes: Verify you’re using the correct ISO codes
  2. Case sensitivity: Country codes should be uppercase (“US”, not “us”)
  3. State code format: Use 2-letter state codes when available
  4. Data availability: Some territories may have incomplete subdivision data
Debugging steps:
// First, verify the country exists
const countries = await api.getCountries();
const country = countries.find(c => c.iso2 === 'US');
console.log('Country found:', country);

// Then check states
const states = await api.getStates('US');
console.log('States count:', states.length);
Use our detailed country endpoint to verify exact country and state codes available.
Performance optimization strategies:
  1. Implement caching (most important)
  2. Use specific endpoints instead of filtering large datasets
  3. Parallel requests for independent data
  4. CDN/Edge caching for static geographical data
Example parallel requests:
// Instead of sequential requests
const countries = await api.getCountries();
const states = await api.getStates('US');

// Use parallel requests
const [countries, states] = await Promise.all([
  api.getCountries(),
  api.getStates('US')
]);
Server-side optimizations:
  • Use HTTP/2 for multiplexed requests
  • Implement connection pooling
  • Add response compression
This is typically due to caching issues or incorrect API usage:Check these common issues:
  1. Browser caching: Different cache states in development
  2. API versioning: Ensure you’re using the same API version
  3. Mixed endpoints: Don’t mix different API base URLs
  4. Concurrent updates: Our data is occasionally updated
Troubleshooting steps:
// Add request debugging
console.log('Request URL:', fullUrl);
console.log('Request headers:', headers);
console.log('Response status:', response.status);
console.log('Response headers:', [...response.headers.entries()]);
Force fresh data:
// Add cache-busting parameter for testing
const url = `${baseUrl}?_t=${Date.now()}`;
If issues persist, contact support with specific request/response examples.
Testing strategy:
  1. Start with cURL to verify basic connectivity
  2. Test each endpoint individually
  3. Verify error handling with invalid inputs
Basic connectivity test:
curl -X GET 'https://api.countrystatecity.in/v1/countries' \
  -H 'X-CSCAPI-KEY: YOUR_API_KEY' \
  -w "HTTP Status: %{http_code}\n"
Automated testing example:
describe('Country State City API', () => {
  test('should fetch countries successfully', async () => {
    const countries = await api.getCountries();
    expect(countries).toBeInstanceOf(Array);
    expect(countries.length).toBeGreaterThan(0);
    expect(countries[0]).toHaveProperty('iso2');
  });

  test('should handle invalid country code', async () => {
    await expect(api.getStates('INVALID')).rejects.toThrow();
  });
});
A successful countries request should return 247+ countries with proper ISO codes.

Still Need Help?

View Examples

Comprehensive integration examples and real-world use cases

API Reference

Complete API documentation with all endpoints and parameters

Contact Support

Get help from our support team
Can’t find what you’re looking for? Contact our support team with specific questions about your integration or use case.