Documentação

Select States

Obtenha estados/provincias por pais, otimizados para dropdowns

O endpoint /v1/select/states retorna uma lista leve de estados/provincias filtrados por pais, com apenas os campos id e name, otimizado para menus dropdown.

Endpoint

GET https://api.countrydataapi.com/v1/select/states

Autenticacao

Inclua sua chave de API como parametro de consulta:

?apikey=sua-chave-api

Sua chave de API e como uma senha, mantenha-a segura. Obtenha sua chave no painel da conta.

Parametros de Consulta

Parametro Tipo Obrigatorio Descricao
apikey string Sim Sua chave de autenticacao da API
country string Sim ID do pais (do endpoint /select/countries)
lang string Nao Codigo do idioma para nomes dos estados (padrao: en)

Idiomas Suportados

  • en - Ingles (padrao)
  • es - Espanhol
  • pt - Portugues
  • fr - Frances
  • de - Alemao
  • it - Italiano

Exemplo de Requisicao

# Obter estados do Brasil
curl "https://api.countrydataapi.com/v1/select/states?apikey=sua-chave-api&country=66c7a6c9e4bda21f4ab10ef5&lang=pt"

JavaScript (Fetch)

const API_KEY = 'sua-chave-api';
const COUNTRY_ID = '66c7a6c9e4bda21f4ab10ef5'; // Brasil

async function carregarEstados(countryId) {
  const response = await fetch(
    `https://api.countrydataapi.com/v1/select/states?apikey=${API_KEY}&country=${countryId}&lang=pt`
  );
  const data = await response.json();
  return data;
}

const estados = await carregarEstados(COUNTRY_ID);

JavaScript (Axios)

import axios from 'axios';

const response = await axios.get(
  'https://api.countrydataapi.com/v1/select/states',
  {
    params: {
      apikey: 'sua-chave-api',
      country: '66c7a6c9e4bda21f4ab10ef5',
      lang: 'pt',
    },
  }
);

Python

import requests

response = requests.get(
    'https://api.countrydataapi.com/v1/select/states',
    params={
        'apikey': 'sua-chave-api',
        'country': '66c7a6c9e4bda21f4ab10ef5',
        'lang': 'pt'
    }
)
data = response.json()

PHP

<?php
$apiKey = 'sua-chave-api';
$countryId = '66c7a6c9e4bda21f4ab10ef5';
$url = "https://api.countrydataapi.com/v1/select/states?apikey={$apiKey}&country={$countryId}&lang=pt";

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);
?>

Angular

// state.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

interface State {
  id: string;
  name: string;
}

interface ApiResponse {
  success: boolean;
  data: State[];
}

@Injectable({
  providedIn: 'root'
})
export class StateService {
  private readonly API_KEY = 'sua-chave-api';
  private readonly BASE_URL = 'https://api.countrydataapi.com/v1';

  constructor(private http: HttpClient) {}

  getStatesByCountry(countryId: string, lang: string = 'pt'): Observable<State[]> {
    const params = new HttpParams()
      .set('apikey', this.API_KEY)
      .set('country', countryId)
      .set('lang', lang);

    return this.http.get<ApiResponse>(
      `${this.BASE_URL}/select/states`,
      { params }
    ).pipe(
      map(response => response.data)
    );
  }
}

// state-select.component.ts
import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { StateService } from './state.service';

@Component({
  selector: 'app-state-select',
  standalone: true,
  imports: [CommonModule, FormsModule],
  template: `
    <div *ngIf="loading">Carregando estados...</div>
    <div *ngIf="error" class="error">{{ error }}</div>
    <select
      *ngIf="!loading && !error"
      [(ngModel)]="selectedState"
      (ngModelChange)="onStateChange($event)"
      [disabled]="!countryId"
    >
      <option value="">Selecione um estado...</option>
      <option *ngFor="let state of states" [value]="state.id">
        {{ state.name }}
      </option>
    </select>
  `
})
export class StateSelectComponent implements OnChanges {
  @Input() countryId: string = '';
  @Output() stateChange = new EventEmitter<string>();

  states: any[] = [];
  selectedState = '';
  loading = false;
  error: string | null = null;

  constructor(private stateService: StateService) {}

  ngOnChanges(changes: SimpleChanges) {
    if (changes['countryId'] && this.countryId) {
      this.loadStates();
    } else {
      this.states = [];
      this.selectedState = '';
    }
  }

  loadStates() {
    this.loading = true;
    this.error = null;

    this.stateService.getStatesByCountry(this.countryId, 'pt').subscribe({
      next: (data) => {
        this.states = data;
        this.loading = false;
      },
      error: (err) => {
        this.error = 'Falha ao carregar estados';
        this.loading = false;
      }
    });
  }

  onStateChange(stateId: string) {
    this.stateChange.emit(stateId);
  }
}

Formato da Resposta

Resposta de Sucesso (Brasil)

{
  "success": true,
  "data": [
    {
      "id": "66c7a6cae4bda21f4ab11d16",
      "name": "Acre"
    },
    {
      "id": "66c7a6cae4bda21f4ab11d17",
      "name": "Alagoas"
    },
    {
      "id": "66c7a6cae4bda21f4ab11d18",
      "name": "Amapa"
    },
    {
      "id": "66c7a6cae4bda21f4ab11d19",
      "name": "Amazonas"
    },
    {
      "id": "66c7a6cae4bda21f4ab11d1a",
      "name": "Bahia"
    }
    // ... 27 estados no total
  ]
}

Campos da Resposta

Campo Tipo Descricao
success boolean Indica se a requisicao foi bem-sucedida
data array Array de objetos de estado/provincia
data[].id string Identificador unico do estado (MongoDB ObjectId)
data[].name string Nome do estado/provincia no idioma solicitado

Resposta de Erro

{
  "success": false,
  "error": {
    "code": "MISSING_PARAMETER",
    "message": "O parametro obrigatorio 'country' esta faltando"
  }
}

Resultado Vazio

Se um pais nao tem estados (ex: paises pequenos):

{
  "success": true,
  "data": []
}

Uso de Tokens

Este endpoint consome 1 token por requisicao.

Dica: Armazene dados de estados por ID do pais em cache para reduzir chamadas de API quando usuarios navegam para tras e para frente.

Exemplo de Dropdown em Cascata

HTML

<select id="country" onchange="carregarEstados(this.value)">
  <option value="">Selecione o pais...</option>
  <!-- Preenchido de /select/countries -->
</select>

<select id="state" disabled>
  <option value="">Selecione o estado...</option>
</select>

<script>
const API_KEY = 'sua-chave-api';

async function carregarEstados(countryId) {
  const stateSelect = document.getElementById('state');

  // Resetar e desabilitar
  stateSelect.innerHTML = '<option value="">Carregando...</option>';
  stateSelect.disabled = true;

  if (!countryId) {
    stateSelect.innerHTML = '<option value="">Selecione o estado...</option>';
    return;
  }

  try {
    const response = await fetch(
      `https://api.countrydataapi.com/v1/select/states?apikey=${API_KEY}&country=${countryId}&lang=pt`
    );
    const { success, data, error } = await response.json();

    if (!success) {
      console.error('Erro da API:', error);
      stateSelect.innerHTML = '<option value="">Erro ao carregar estados</option>';
      return;
    }

    stateSelect.innerHTML = '<option value="">Selecione o estado...</option>';
    data.forEach(state => {
      stateSelect.add(new Option(state.name, state.id));
    });
    stateSelect.disabled = false;
  } catch (err) {
    console.error('Erro de Rede:', err);
    stateSelect.innerHTML = '<option value="">Erro ao carregar estados</option>';
  }
}
</script>

Componente React

import { useState, useEffect } from 'react';

function StateSelect({ countryId, onChange }) {
  const [states, setStates] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    if (!countryId) {
      setStates([]);
      return;
    }

    setLoading(true);
    fetch(
      `https://api.countrydataapi.com/v1/select/states?apikey=sua-chave-api&country=${countryId}&lang=pt`
    )
      .then(res => res.json())
      .then(({ data }) => {
        setStates(data || []);
        setLoading(false);
      })
      .catch(err => {
        console.error(err);
        setLoading(false);
      });
  }, [countryId]);

  return (
    <select onChange={e => onChange(e.target.value)} disabled={!countryId || loading}>
      <option value="">
        {loading ? 'Carregando...' : 'Selecione o estado...'}
      </option>
      {states.map(state => (
        <option key={state.id} value={state.id}>
          {state.name}
        </option>
      ))}
    </select>
  );
}

Componente Vue

<script setup>
import { ref, watch } from 'vue';

const props = defineProps(['countryId']);
const emit = defineEmits(['change']);

const states = ref([]);
const loading = ref(false);

watch(() => props.countryId, async (countryId) => {
  if (!countryId) {
    states.value = [];
    return;
  }

  loading.value = true;
  try {
    const response = await fetch(
      `https://api.countrydataapi.com/v1/select/states?apikey=sua-chave-api&country=${countryId}&lang=pt`
    );
    const { data } = await response.json();
    states.value = data || [];
  } catch (err) {
    console.error(err);
  } finally {
    loading.value = false;
  }
});
</script>

<template>
  <select @change="emit('change', $event.target.value)" :disabled="!countryId || loading">
    <option value="">{{ loading ? 'Carregando...' : 'Selecione o estado...' }}</option>
    <option v-for="state in states" :key="state.id" :value="state.id">
      {{ state.name }}
    </option>
  </select>
</template>

Exemplos por Pais

Brasil (27 estados)

const BRAZIL_ID = '66c7a6c9e4bda21f4ab10ef5';
const response = await fetch(
  `https://api.countrydataapi.com/v1/select/states?apikey=sua-chave-api&country=${BRAZIL_ID}&lang=pt`
);
// Retorna: Acre, Alagoas, Amapa, ... Tocantins

Portugal (18 distritos + 2 regioes autonomas)

const PORTUGAL_ID = '66c7a6c9e4bda21f4ab10fc5';
const response = await fetch(
  `https://api.countrydataapi.com/v1/select/states?apikey=sua-chave-api&country=${PORTUGAL_ID}&lang=pt`
);
// Retorna: Aveiro, Beja, ... Acores, Madeira

Estados Unidos (50 estados)

const US_ID = '66c7a6c9e4bda21f4ab10fd5';
const response = await fetch(
  `https://api.countrydataapi.com/v1/select/states?apikey=sua-chave-api&country=${US_ID}&lang=pt`
);
// Retorna: Alabama, Alaska, Arizona, ... Wyoming

Estrategia de Cache

Armazene estados por pais em cache para minimizar chamadas de API:

const stateCache = new Map();

async function getEstados(countryId) {
  // Verificar cache primeiro
  if (stateCache.has(countryId)) {
    return stateCache.get(countryId);
  }

  // Buscar da API
  const response = await fetch(
    `https://api.countrydataapi.com/v1/select/states?apikey=sua-chave-api&country=${countryId}&lang=pt`
  );
  const { data } = await response.json();

  // Salvar em cache
  stateCache.set(countryId, data);

  return data;
}

Tratamento de Erros

Sempre trate erros de forma elegante:

async function carregarEstados(countryId) {
  try {
    const response = await fetch(
      `https://api.countrydataapi.com/v1/select/states?apikey=sua-chave-api&country=${countryId}`
    );

    if (!response.ok) {
      throw new Error(`Erro HTTP! status: ${response.status}`);
    }

    const result = await response.json();

    if (!result.success) {
      throw new Error(result.error?.message || 'Erro da API');
    }

    return result.data;
  } catch (err) {
    console.error('Falha ao carregar estados:', err);
    // Mostrar mensagem amigavel ao usuario
    alert('Falha ao carregar estados. Por favor, tente novamente.');
    return [];
  }
}

Dicas de Performance

  1. Carregamento lazy: So buscar quando o pais for selecionado
  2. Cache por pais: Armazenar em memoria ou localStorage
  3. Debounce nas requisicoes: Se usar busca/filtro
  4. Mostrar estado de carregamento: Fornecer feedback visual

Limites de Taxa

  • Plano gratuito: 100 requisicoes/dia
  • Plano Basic: 1.000 requisicoes/dia
  • Plano Pro: 10.000 requisicoes/dia
  • Plano Enterprise: Ilimitado

Confira nossa pagina de precos para mais detalhes.

Erros Comuns

Codigo de Erro Descricao Solucao
INVALID_API_KEY Chave de API invalida Verifique sua chave de API no painel da conta
MISSING_PARAMETER Parametro country faltando Inclua o ID do pais na requisicao
INVALID_COUNTRY_ID Formato do ID do pais invalido Use um MongoDB ObjectId valido de /select/countries
QUOTA_EXCEEDED Limite diario de tokens atingido Atualize o plano ou aguarde o reset

Consulte a documentacao de Codigos de Erro para todos os erros possiveis.

Endpoints Relacionados

Guias de Integracao Completos

Precisa de Ajuda?


Nota: Alguns paises nao tem divisoes administrativas (ex: Monaco, Cidade do Vaticano) e retornarao um array vazio. Sempre trate resultados vazios de forma elegante na sua interface.