Cities
Retrieve list of available cities for customer registration and shipping addresses.
Get All Cities
GET /api/ecom/ciudad Get complete list of available cities
Retrieve all cities available in the system for use in customer registration, shipping addresses, and location-based features.
This endpoint does not require authentication and can be accessed publicly to populate city dropdowns and location selectors.
Response
Array of city objects Show City object properties
City unique code/identifier
Whether the city is active for selection
Example Request
curl -X GET https://api.example.com/api/ecom/ciudad
Example Response
[
{
"ct_codigo" : "UIO" ,
"ct_nombre" : "Quito" ,
"ct_provincia" : "Pichincha" ,
"ct_pais" : "Ecuador" ,
"ct_activo" : true
},
{
"ct_codigo" : "GYE" ,
"ct_nombre" : "Guayaquil" ,
"ct_provincia" : "Guayas" ,
"ct_pais" : "Ecuador" ,
"ct_activo" : true
},
{
"ct_codigo" : "CUE" ,
"ct_nombre" : "Cuenca" ,
"ct_provincia" : "Azuay" ,
"ct_pais" : "Ecuador" ,
"ct_activo" : true
},
{
"ct_codigo" : "AMB" ,
"ct_nombre" : "Ambato" ,
"ct_provincia" : "Tungurahua" ,
"ct_pais" : "Ecuador" ,
"ct_activo" : true
},
{
"ct_codigo" : "MCH" ,
"ct_nombre" : "Machala" ,
"ct_provincia" : "El Oro" ,
"ct_pais" : "Ecuador" ,
"ct_activo" : true
}
]
Use Cases
Customer Registration
When registering a new customer, the city code is required as part of the customer details:
// 1. Fetch available cities
const citiesResponse = await fetch ( 'https://api.example.com/api/ecom/ciudad' );
const cities = await citiesResponse . json ();
// 2. User selects city from dropdown
const selectedCityCode = 'UIO' ; // User selection
// 3. Include in registration
const registerResponse = await fetch ( 'https://api.example.com/api/ecom/auth/register' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({
email: '[email protected] ' ,
password: 'securePassword123' ,
cli_ruc_ced: '1234567890' ,
cliente: {
cli_nombre: 'Juan Pérez' ,
cli_telefono: '0987654321' ,
cli_celular: '987654321' ,
cli_direccion: 'Av. Principal 123' ,
ct_codigo: selectedCityCode // City code from cities list
}
})
});
Populate city selectors in address forms:
JavaScript - Dynamic Dropdown
Python - City Lookup
async function loadCities () {
try {
const response = await fetch ( 'https://api.example.com/api/ecom/ciudad' );
const cities = await response . json ();
const select = document . getElementById ( 'city-select' );
// Clear existing options
select . innerHTML = '<option value="">Seleccione una ciudad</option>' ;
// Add cities grouped by province
const provinces = {};
cities . forEach ( city => {
if ( ! provinces [ city . ct_provincia ]) {
provinces [ city . ct_provincia ] = [];
}
provinces [ city . ct_provincia ]. push ( city );
});
// Create optgroups
Object . keys ( provinces ). sort (). forEach ( province => {
const optgroup = document . createElement ( 'optgroup' );
optgroup . label = province ;
provinces [ province ]. forEach ( city => {
const option = document . createElement ( 'option' );
option . value = city . ct_codigo ;
option . textContent = city . ct_nombre ;
optgroup . appendChild ( option );
});
select . appendChild ( optgroup );
});
} catch ( error ) {
console . error ( 'Failed to load cities:' , error );
}
}
// Load on page load
loadCities ();
Filtering and Search
Implement city search and filtering:
async function searchCities ( query ) {
const response = await fetch ( 'https://api.example.com/api/ecom/ciudad' );
const cities = await response . json ();
const searchTerm = query . toLowerCase ();
return cities . filter ( city =>
city . ct_nombre . toLowerCase (). includes ( searchTerm ) ||
city . ct_provincia . toLowerCase (). includes ( searchTerm ) ||
city . ct_codigo . toLowerCase (). includes ( searchTerm )
);
}
// Usage
const results = await searchCities ( 'qui' );
// Returns cities matching 'qui' (e.g., Quito)
Data Structure
City Code (ct_codigo)
The city code is typically a 3-letter abbreviation:
UIO : Quito
GYE : Guayaquil
CUE : Cuenca
AMB : Ambato
MCH : Machala
City codes are used as foreign keys in customer records and should be validated against the cities list before submission.
Active Status (ct_activo)
Cities have an active flag to indicate if they’re available for selection:
true: City is active and can be selected
false: City is inactive (historical data only)
Inactive cities may still appear in the API response but should typically be filtered out in UI dropdowns. They’re kept for maintaining referential integrity with existing customer records.
Response Characteristics
Empty Response
If no cities are configured in the system, the endpoint returns an empty array:
This is a valid response (200 OK) and should be handled gracefully in client applications.
Response Size
The cities list is typically small (dozens to hundreds of entries) and can be:
Cached client-side for performance
Loaded once on application startup
Refreshed periodically if cities change
Unlike other list endpoints, the cities endpoint returns all cities in a single response without pagination. This is intentional as:
The dataset is small
Cities are needed in full for dropdown population
Pagination would complicate UI implementation
Integration with Registration
The city code is used during customer registration:
POST /api/ecom/auth/register
{
"email" : "[email protected] " ,
"password" : "securePassword123" ,
"cli_ruc_ced" : "1234567890" ,
"cliente" : {
"cli_nombre" : "Juan Pérez" ,
"cli_telefono" : "0987654321" ,
"cli_celular" : "987654321" ,
"cli_direccion" : "Av. Principal 123" ,
"ct_codigo" : "UIO" // <- City code from cities list
}
}
Always validate that the ct_codigo provided during registration exists in the cities list returned by this endpoint. Using an invalid city code will cause registration to fail.
Best Practices
Client-Side Caching
Cache the cities list to reduce API calls:
class CityService {
constructor () {
this . cache = null ;
this . cacheTime = null ;
this . cacheDuration = 3600000 ; // 1 hour
}
async getCities () {
const now = Date . now ();
// Return cached data if still valid
if ( this . cache && ( now - this . cacheTime ) < this . cacheDuration ) {
return this . cache ;
}
// Fetch fresh data
const response = await fetch ( 'https://api.example.com/api/ecom/ciudad' );
this . cache = await response . json ();
this . cacheTime = now ;
return this . cache ;
}
invalidateCache () {
this . cache = null ;
this . cacheTime = null ;
}
}
const cityService = new CityService ();
Dropdown Organization
Group cities by province for better UX:
< select id = "city-select" >
< option value = "" > Seleccione una ciudad </ option >
< optgroup label = "Pichincha" >
< option value = "UIO" > Quito </ option >
</ optgroup >
< optgroup label = "Guayas" >
< option value = "GYE" > Guayaquil </ option >
</ optgroup >
< optgroup label = "Azuay" >
< option value = "CUE" > Cuenca </ option >
</ optgroup >
</ select >
Error Handling
Handle cases where cities cannot be loaded:
async function loadCitiesWithFallback () {
try {
const response = await fetch ( 'https://api.example.com/api/ecom/ciudad' );
if ( ! response . ok ) {
throw new Error ( 'Failed to fetch cities' );
}
const cities = await response . json ();
if ( cities . length === 0 ) {
console . warn ( 'No cities available' );
showMessage ( 'No hay ciudades disponibles en este momento' );
return [];
}
return cities ;
} catch ( error ) {
console . error ( 'Error loading cities:' , error );
showMessage ( 'Error al cargar las ciudades. Por favor, intente nuevamente.' );
return [];
}
}
Error Responses
500 Internal Server Error
{
"message" : "Error message details"
}
The endpoint returns a 500 status code only in case of server errors. Empty city lists return 200 with an empty array.
Source Code Reference
Implementation details can be found in:
Routes: /src/routes/ecom.ciudad.routes.js:1-9
Controller: /src/controllers/ecom.ciudad.controller.js:6-25
Model: /src/models/ciudad.model.js
Database: E-Commerce database connection via /src/config/db_ecom.js
The cities data is used in conjunction with:
Customer Registration : POST /api/ecom/auth/register - requires ct_codigo in customer details
Customer Profile : GET /api/ecom/auth/me - returns customer’s city information
This endpoint provides reference data for location-based features across the e-commerce platform. The city codes are standardized and must match between registration, profile management, and shipping operations.