> ## Documentation Index
> Fetch the complete documentation index at: https://docs.countrystatecity.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Get States by Country

> Retrieve all states/provinces for a specific country

Retrieve all states, provinces, regions, and territories for a specific country using the country's ISO2 code.

<Note>**Availability:** All plans (Community and above). The fields returned vary by tier — see **Tier-Based Field Availability** below.</Note>

<Tip>
  **Trim and order results:** Add `?fields=` to limit columns returned, or `?sort=` to order the list. Both are available on **Starter+** plans. See the [Field Filtering & Sorting](/api/field-filtering-and-sorting) guide for syntax and per-entity sortable fields.
</Tip>

<Info>Additional fields like `fips_code`, `iso3166_2`, `type`, `level`, `parent_id`, `native`, `population`, `translations`, and `wikiDataId` are returned on higher tiers. See **Tier-Based Field Availability** below.</Info>

<RequestExample>
  ```bash cURL theme={null}
  curl -X GET 'https://api.countrystatecity.in/v1/countries/IN/states' \
    -H 'X-CSCAPI-KEY: YOUR_API_KEY'
  ```

  ```bash cURL (with search) theme={null}
  curl -X GET 'https://api.countrystatecity.in/v1/countries/IN/states?q=maha' \
    -H 'X-CSCAPI-KEY: YOUR_API_KEY'
  ```

  ```bash cURL (with translations) theme={null}
  curl -X GET 'https://api.countrystatecity.in/v1/countries/IN/states?include_translations=true' \
    -H 'X-CSCAPI-KEY: YOUR_API_KEY'
  ```

  ```python Python theme={null}
  import requests

  def get_states_by_country(country_code):
      response = requests.get(
        f'https://api.countrystatecity.in/v1/countries/{country_code}/states',
        headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
      )
      
      if response.ok:
          states = response.json()
          print(f'Found {len(states)} states in {country_code}')
          return states
      else:
          print('Country not found or no states available')
          return []

  states = get_states_by_country('IN')
  ```

  ```javascript JavaScript theme={null}
  const getStatesByCountry = async (countryCode) => {
    const response = await fetch(`https://api.countrystatecity.in/v1/countries/${countryCode}/states`, {
      headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' }
    });

    if (response.ok) {
      const states = await response.json();
      console.log(`Found ${states.length} states in ${countryCode}`);
      return states;
    } else {
      console.error('Country not found or no states available');
    }
  };

  getStatesByCountry('IN');
  ```

  ```php PHP theme={null}
  <?php
  function getStatesByCountry($countryCode) {
      $curl = curl_init();
      
      curl_setopt_array($curl, array(
        CURLOPT_URL => "https://api.countrystatecity.in/v1/countries/{$countryCode}/states",
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => array(
          'X-CSCAPI-KEY: YOUR_API_KEY'
        ),
      ));
      
      $response = curl_exec($curl);
      $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
      curl_close($curl);
      
      if ($httpCode == 200) {
          $states = json_decode($response, true);
          echo "Found " . count($states) . " states in {$countryCode}\n";
          return $states;
      } else {
          echo "Country not found or no states available\n";
          return [];
      }
  }

  $states = getStatesByCountry('IN');
  ?>
  ```

  ```go Go theme={null}
  package main

  import (
      "encoding/json"
      "fmt"
      "io/ioutil"
      "net/http"
  )

  func getStatesByCountry(countryCode string) []map[string]interface{} {
      url := fmt.Sprintf("https://api.countrystatecity.in/v1/countries/%s/states", countryCode)
      
      client := &http.Client{}
      req, _ := http.NewRequest("GET", url, nil)
      req.Header.Add("X-CSCAPI-KEY", "YOUR_API_KEY")
      
      res, _ := client.Do(req)
      defer res.Body.Close()
      
      if res.StatusCode == 200 {
          body, _ := ioutil.ReadAll(res.Body)
          var states []map[string]interface{}
          json.Unmarshal(body, &states)
          
          fmt.Printf("Found %d states in %s\n", len(states), countryCode)
          return states
      } else {
          fmt.Printf("Country not found or no states available\n")
          return nil
      }
  }

  func main() {
      states := getStatesByCountry("IN")
      fmt.Println(states)
  }
  ```

  ```java Java theme={null}
  import java.net.URI;
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpResponse;
  import com.google.gson.Gson;
  import com.google.gson.reflect.TypeToken;
  import java.lang.reflect.Type;
  import java.util.List;
  import java.util.Map;

  public class StatesByCountry {
      public static void main(String[] args) throws Exception {
          String countryCode = "IN";
          
          HttpClient client = HttpClient.newHttpClient();
          HttpRequest request = HttpRequest.newBuilder()
              .uri(URI.create("https://api.countrystatecity.in/v1/countries/" + countryCode + "/states"))
              .header("X-CSCAPI-KEY", "YOUR_API_KEY")
              .build();

          HttpResponse<String> response = client.send(request,
              HttpResponse.BodyHandlers.ofString());
              
          if (response.statusCode() == 200) {
              Gson gson = new Gson();
              Type listType = new TypeToken<List<Map<String, Object>>>(){}.getType();
              List<Map<String, Object>> states = gson.fromJson(response.body(), listType);
              
              System.out.println("Found " + states.size() + " states in " + countryCode);
          } else {
              System.out.println("Country not found or no states available");
          }
      }
  }
  ```

  ```ruby Ruby theme={null}
  require 'net/http'
  require 'json'

  def get_states_by_country(country_code)
    uri = URI("https://api.countrystatecity.in/v1/countries/#{country_code}/states")
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true

    request = Net::HTTP::Get.new(uri)
    request['X-CSCAPI-KEY'] = 'YOUR_API_KEY'

    response = http.request(request)
    
    if response.code == '200'
      states = JSON.parse(response.body)
      puts "Found #{states.length} states in #{country_code}"
      states
    else
      puts 'Country not found or no states available'
      []
    end
  end

  states = get_states_by_country('IN')
  ```
</RequestExample>

<ResponseExample>
  ```json 200 - Basic tier (Community, Starter, Legacy) theme={null}
  [
    {
      "id": 4008,
      "name": "Maharashtra",
      "iso2": "MH",
      "country_id": 101,
      "country_code": "IN",
      "latitude": "19.75147980",
      "longitude": "75.71388840",
      "timezone": "Asia/Kolkata"
    }
  ]
  ```

  ```json 200 - Full tier, with translations (Supporter, Professional, Business) theme={null}
  [
    {
      "id": 4008,
      "name": "Maharashtra",
      "iso2": "MH",
      "country_id": 101,
      "country_code": "IN",
      "latitude": "19.75147980",
      "longitude": "75.71388840",
      "timezone": "Asia/Kolkata",
      "fips_code": "16",
      "iso3166_2": "IN-MH",
      "type": "state",
      "level": 1,
      "parent_id": null,
      "native": "महाराष्ट्र",
      "population": 112374333,
      "translations": "{\"kr\":\"마하라슈트라\",\"de\":\"Maharashtra\",\"fr\":\"Maharashtra\",\"cn\":\"马哈拉施特拉邦\"}",
      "wikiDataId": "Q1191"
    }
  ]
  ```

  ```json 404 - Not Found theme={null}
  {
    "error": "No States/Regions found."
  }
  ```

  ```json 401 - Unauthorized theme={null}
  {
    "error": "Unauthorized. You shouldn't be here."
  }
  ```
</ResponseExample>

## Common Use Cases

<AccordionGroup>
  <Accordion title="Cascading Address Forms">
    Create dependent dropdowns where states populate based on country selection.

    ```javascript theme={null}
    const populateStatesDropdown = async (countryCode) => {
      const states = await getStatesByCountry(countryCode);
      const select = document.getElementById('state-select');
      
      // Clear existing options
      select.innerHTML = '<option value="">Select State...</option>';
      
      states.forEach(state => {
        const option = document.createElement('option');
        option.value = state.iso2;
        option.textContent = state.name;
        select.appendChild(option);
      });
    };

    // Listen for country changes
    document.getElementById('country-select').addEventListener('change', (e) => {
      populateStatesDropdown(e.target.value);
    });
    ```
  </Accordion>

  <Accordion title="Regional Validation">
    Validate state codes against specific countries.

    ```javascript theme={null}
    const validateStateForCountry = async (countryCode, stateCode) => {
      const states = await getStatesByCountry(countryCode);
      return states.some(state => state.iso2 === stateCode);
    };
    ```
  </Accordion>
</AccordionGroup>

<Tip>
  Cache states by country as they rarely change. Use this endpoint instead of filtering all states for better performance.
</Tip>

## Tier-Based Field Availability

| Tier | Plans | Fields |
| - | - | - |
| **Basic** | Community, Starter, Legacy | `id`, `name`, `iso2`, `country_id`, `country_code`, `latitude`, `longitude`, `timezone` |
| **Full** | Supporter, Professional, Business | All Basic **+** `fips_code`, `iso3166_2`, `type`, `level`, `parent_id`, `native`, `population`, `translations`, `wikiDataId`, `localized_name`, `matched_locale` |

`translations` is part of Full access but is not returned by default: add `include_translations=true`, or name it in `?fields=`. `localized_name` and `matched_locale` are computed from the translations rather than stored, and appear only when you pass `locale`. See [Localized Place Names](/api/localization).

See [Pricing](https://app.countrystatecity.in/pricing) for plan details.


## OpenAPI

````yaml GET /countries/{ciso}/states
openapi: 3.0.3
info:
  title: Country State City API
  description: >-
    Geographic data API providing countries, states, cities, timezones,
    currencies, and phone dial codes with tiered access levels.


    ## Authentication

    All endpoints require an API key passed via the `X-CSCAPI-KEY` header. Get
    your free key at [app.countrystatecity.in](https://app.countrystatecity.in).


    ## Pricing & Limits

    The fields returned, endpoints available, and request quotas depend on your
    plan. See current tiers and limits at:


    **[countrystatecity.in/pricing](https://countrystatecity.in/pricing)**


    ## Data Access Levels

    Each plan includes a data access level that controls which fields are
    returned:


    - **Basic** — Core fields: id, name, iso2, iso3, phonecode, capital,
    currency, coordinates, region, timezones, emoji

    - **Coordinates** — Basic + extended metadata (population, tld, nationality,
    currency details, postal codes, etc.)

    - **Full** — All fields including translations (18+ languages) and
    wikiDataId


    Fields restricted to higher tiers are marked in each schema below.


    ## Feature Gating

    Some endpoints require a minimum tier. Restricted endpoints return `403`
    with an `upgradeUrl` when accessed on a lower plan. Check the [pricing
    page](https://countrystatecity.in/pricing) for current feature availability.


    ## Rate Limiting

    Requests exceeding your daily or monthly quota receive a `429` response with
    your current limit, period, tier, and an upgrade URL.


    ## Caching

    Cacheable geographic responses include `Cache-Control`, `ETag`, and
    `X-Cache` (HIT/MISS) headers; send `If-None-Match` on them to receive `304
    Not Modified`. Phone number parsing is never cached (`Cache-Control:
    no-store`, no `ETag`); see each endpoint for exceptions.


    ## Usage Headers

    All `/v1/*` responses include usage and plan headers:

    - `X-CSC-Plan` — your current tier

    - `X-CSC-Daily-Used` / `X-CSC-Daily-Limit` — today's usage vs limit

    - `X-CSC-Monthly-Used` / `X-CSC-Monthly-Limit` — this month's usage vs limit


    Use these to monitor consumption without a separate API call.
  contact:
    name: Darshan Gada (dr5hn)
    email: gadadarshan@gmail.com
    url: https://countrystatecity.in
  license:
    name: Creative Commons Attribution 4.0
    url: https://creativecommons.org/licenses/by/4.0/
  version: 2.4.1
servers:
  - url: https://api.countrystatecity.in/v1
    description: Production API
security: []
tags:
  - name: Countries
    description: Country data — 250+ countries with metadata, coordinates, and translations
  - name: States
    description: State/province/region data — 5,000+ subdivisions
  - name: Cities
    description: City data — 150,000+ cities worldwide
  - name: Postcodes
    description: >-
      Postcode and ZIP code lookup and search. Informational data, not address
      verification.
  - name: Regions
    description: Geographic regions and subregions — continental groupings of countries
  - name: Timezones
    description: >-
      IANA timezone lookup by country, state, or city — includes UTC offset and
      DST status
  - name: Currencies
    description: ISO 4217 currency data — list all currencies or look up by country
  - name: Phone
    description: >-
      International dial codes — list, lookup by country, and E.164 phone number
      parsing
  - name: ISO
    description: >-
      ISO 3166 code lookup and conversion — country (alpha-2/3/numeric) and
      state (ISO 3166-2)
  - name: Search
    description: Typo-tolerant fuzzy search across cities, states, and countries
  - name: Changes
    description: >-
      Data change feed — track additions, removals, and updates to place records
      over time. **Professional and Business plans only.**
  - name: Meta
    description: Information about the dataset release currently served
paths:
  /countries/{ciso}/states:
    get:
      tags:
        - States
      summary: Get states of a country
      description: |-
        Returns all states/provinces/regions for the specified country.

        **Availability:** All tiers
      operationId: getCountryStates
      parameters:
        - name: ciso
          in: path
          description: ISO2 code of the country (e.g., `IN`)
          required: true
          schema:
            type: string
            example: IN
        - name: q
          in: query
          description: >-
            Search filter. Case-insensitive match on `name` and `native` fields.
            Min 2 characters. **Requires Starter+ plan.**
          required: false
          schema:
            type: string
            minLength: 2
            maxLength: 100
            example: maha
        - name: fields
          in: query
          description: >-
            Comma-separated list of fields to include in the response. `id` is
            always included. **Requires Starter+ plan.**
          required: false
          schema:
            type: string
            example: name,iso2
        - name: sort
          in: query
          description: >-
            Comma-separated sort tokens: `field` or `field:asc|desc`. **Requires
            Starter+ plan.**
          required: false
          schema:
            type: string
            example: name:asc
        - name: locale
          in: query
          description: >-
            BCP 47 locale code (e.g. `pt-BR`) to request a localized name. Adds
            `localized_name` (resolved via exact locale → base language → native
            name → English name fallback) and `matched_locale` (which tier
            matched) to each result; `name` is unaffected. **Supporter+ plans
            only** — silently omitted (not an error) on lower tiers. A malformed
            value is rejected with a `400` on every tier.
          required: false
          schema:
            type: string
            minLength: 2
            maxLength: 7
            pattern: ^[a-zA-Z]{2}(-[a-zA-Z]{2,4})?$
            example: pt-BR
        - name: include_translations
          in: query
          description: >-
            When `true`, includes the full `translations` field (JSON string
            keyed by language code). **Supporter+ plans only** — silently
            omitted (not an error) on lower tiers. Note that an explicit
            `fields=translations` also returns the field and takes precedence
            over this flag.
          required: false
          schema:
            type: boolean
            default: false
            example: true
      responses:
        '200':
          description: List of states
          headers:
            Cache-Control:
              $ref: '#/components/headers/CacheControl'
            ETag:
              $ref: '#/components/headers/ETag'
            X-Cache:
              $ref: '#/components/headers/XCache'
            X-CSC-Plan:
              $ref: '#/components/headers/XCSCPlan'
            X-CSC-Daily-Used:
              $ref: '#/components/headers/XCSCDailyUsed'
            X-CSC-Daily-Limit:
              $ref: '#/components/headers/XCSCDailyLimit'
            X-CSC-Monthly-Used:
              $ref: '#/components/headers/XCSCMonthlyUsed'
            X-CSC-Monthly-Limit:
              $ref: '#/components/headers/XCSCMonthlyLimit'
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/State'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/FeatureRestricted'
        '429':
          $ref: '#/components/responses/RateLimited'
      security:
        - ApiKeyAuth: []
components:
  headers:
    CacheControl:
      description: Cache directive
      schema:
        type: string
        example: public, max-age=3600
    ETag:
      description: Entity tag for conditional requests (use with `If-None-Match`)
      schema:
        type: string
        example: '"a3f2b8c1d4e5f6a7b8c9d0e1f2a3b4c5"'
    XCache:
      description: Whether the response was served from cache
      schema:
        type: string
        enum:
          - HIT
          - MISS
        example: HIT
    XCSCPlan:
      description: Your current pricing tier
      schema:
        type: string
        enum:
          - community
          - starter
          - supporter
          - professional
          - business
          - legacy
          - custom
        example: supporter
    XCSCDailyUsed:
      description: Number of requests used today
      schema:
        type: integer
        example: 42
    XCSCDailyLimit:
      description: Your daily request limit (or 'unlimited' for custom plans)
      schema:
        type: string
        example: '1000'
    XCSCMonthlyUsed:
      description: Number of requests used this month
      schema:
        type: integer
        example: 850
    XCSCMonthlyLimit:
      description: Your monthly request limit (or 'unlimited' for custom plans)
      schema:
        type: string
        example: '30000'
  schemas:
    State:
      type: object
      description: >-
        State/province/region object. Fields returned depend on your plan's data
        access level.
      properties:
        id:
          type: integer
          format: int64
          description: Unique identifier
          example: 4008
        name:
          type: string
          description: State name in English
          example: Maharashtra
        iso2:
          type: string
          nullable: true
          description: State/province ISO code
          example: MH
        country_id:
          type: integer
          format: int64
          description: Parent country ID
        country_code:
          type: string
          description: Parent country ISO2 code
          example: IN
        latitude:
          type: string
          nullable: true
          description: Latitude coordinate
          example: '19.75147980'
        longitude:
          type: string
          nullable: true
          description: Longitude coordinate
          example: '75.71388840'
        timezone:
          type: string
          nullable: true
          description: IANA timezone identifier
          example: Asia/Kolkata
        fips_code:
          type: string
          nullable: true
          description: FIPS code. **Coordinates tier and above.**
        iso3166_2:
          type: string
          nullable: true
          description: ISO 3166-2 subdivision code. **Coordinates tier and above.**
        type:
          type: string
          nullable: true
          description: >-
            Administrative type (e.g., state, province, territory).
            **Coordinates tier and above.**
          example: state
        level:
          type: integer
          nullable: true
          description: Administrative level. **Coordinates tier and above.**
        parent_id:
          type: integer
          format: int64
          nullable: true
          description: >-
            Parent subdivision ID (for nested administrative structures).
            **Coordinates tier and above.**
        native:
          type: string
          nullable: true
          description: Name in native language. **Coordinates tier and above.**
        population:
          type: integer
          format: int64
          nullable: true
          description: Population count. **Coordinates tier and above.**
        translations:
          type: string
          nullable: true
          description: >-
            JSON string keyed by language code. **Supporter+ plans only.**
            Returned when `include_translations=true` or when
            `fields=translations` explicitly requests it.
        wikiDataId:
          type: string
          nullable: true
          description: Wikidata item identifier. **Full access level only.**
          example: Q1191
        localized_name:
          type: string
          nullable: true
          description: >-
            Name resolved via the `locale` query param's fallback chain (exact
            locale → base language → native name → English name). Only present
            when `locale` was supplied. **Supporter+ plans only** — silently
            omitted on lower tiers.
          example: Maharashtra
        matched_locale:
          type: string
          nullable: true
          description: >-
            Which fallback tier satisfied the `locale` request: the exact locale
            (e.g. `pt-BR`), its base language (e.g. `pt`), `native`, or `en`
            (English fallback). Only present when `locale` was supplied.
            **Supporter+ plans only** — silently omitted on lower tiers.
          example: en
      required:
        - id
        - name
        - country_id
        - country_code
    Error:
      type: object
      properties:
        error:
          type: string
          description: Error message
      required:
        - error
    FeatureError:
      type: object
      properties:
        status:
          type: string
          enum:
            - error
        message:
          type: string
          example: This feature is not available on your current plan.
        details:
          type: object
          properties:
            feature:
              type: string
              description: The feature flag that was denied
              example: bulkStates
            currentTier:
              type: string
              example: community
            requiredTier:
              type: string
              nullable: true
              description: >-
                Lowest plan that unlocks the feature; null when it cannot be
                determined
              example: starter
            upgradeUrl:
              type: string
              format: uri
              example: https://countrystatecity.in/pricing
          required:
            - feature
            - currentTier
            - requiredTier
            - upgradeUrl
      required:
        - status
        - message
        - details
    RateLimitError:
      type: object
      properties:
        error:
          type: string
          example: >-
            Daily usage limit exceeded. Please try again tomorrow or contact
            support for higher limits.
        limit:
          type: integer
          description: Your plan's limit for the exceeded period
          example: 100
        period:
          type: string
          enum:
            - daily
            - monthly
          example: daily
        tier:
          type: string
          description: Your current tier
          example: community
        upgradeUrl:
          type: string
          description: URL to upgrade your plan
          example: https://countrystatecity.in/pricing
      required:
        - error
  responses:
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Unauthorized. You shouldn't be here.
    FeatureRestricted:
      description: >-
        Feature not available on your current plan. Upgrade to access this
        endpoint. `details.feature` names the denied feature and
        `details.requiredTier` the lowest plan that includes it (the example is
        for `/states`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/FeatureError'
          example:
            status: error
            message: This feature is not available on your current plan.
            details:
              feature: bulkStates
              currentTier: community
              requiredTier: starter
              upgradeUrl: https://countrystatecity.in/pricing
    RateLimited:
      description: Daily or monthly usage limit exceeded
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/RateLimitError'
          example:
            error: >-
              Daily usage limit exceeded. Please try again tomorrow or contact
              support for higher limits.
            limit: 100
            period: daily
            tier: community
            upgradeUrl: https://countrystatecity.in/pricing
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      description: >-
        API key for authentication. Get your free key at
        [app.countrystatecity.in](https://app.countrystatecity.in).
      name: X-CSCAPI-KEY
      in: header

````

## Related topics

- [Country State City API](/api/introduction.md)
- [Lookup State by ISO Code](/api/endpoints/lookup-state-by-iso.md)
- [Export Formats](/tools/export-tool/formats.md)
- [Get Cities by State](/api/endpoints/get-cities-by-state.md)
- [Get Timezone by State](/api/endpoints/get-timezone-by-state.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.