Configurar tus sucursales
Crear, corregir y desactivar las sucursales del workspace.
GET /locations devuelve las sucursales del workspace. Una sucursal es el lugar físico donde se atiende y se agenda. Casi todo lo que tiene un lugar la lleva embebida o la referencia por id: una cita, una unidad del catálogo, un miembro del equipo.
Es el bloque sucursal que viene embebido en cada unidad del
stock y el valor del filtro ?sucursal=.
Cinco endpoints, CRUD completo. Leer pide tenant:read; escribir, tenant:write. El contrato campo por campo está en la referencia.
Ver las que hay
curl https://api.vitrinadev.com/api/v1/locations \
-H "Authorization: Bearer $VITRINA_KEY"En un workspace recién creado:
{ "data": [] }Esta lista no pagina y no trae meta.
Crear una
Solo name es obligatorio. Todo lo demás ayuda a que la sucursal se vea bien donde se muestre:
curl -X POST https://api.vitrinadev.com/api/v1/locations \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Sucursal Providencia",
"address_street": "Av. Nueva Providencia",
"address_number": "2214",
"comuna_code": "13123",
"phone": "+56229876543",
"email": "[email protected]",
"timezone": "America/Santiago"
}'{
"data": {
"id": "6812d9f0-9bed-44b5-91df-4e5b90941f6b",
"tenant_id": "00000000-0000-4000-8000-000000000001",
"name": "Sucursal Providencia",
"address": null,
"address_street": "Av. Nueva Providencia",
"address_number": "2214",
"address_unit": null,
"comuna_code": "13123",
"region_code": "13",
"address_source": "manual",
"phone": "+56229876543",
"email": "[email protected]",
"manager_name": null,
"hours": null,
"timezone": "America/Santiago",
"geo": null,
"notes": null,
"arrival_info": null,
"metadata": {},
"is_active": true,
"display_seq": 1,
"display_id": "B-1",
"created_at": "2026-09-15T18:34:09.375Z",
"updated_at": "2026-09-15T18:34:09.375Z"
}
}Tres campos que no van en el cuerpo y sin embargo están:
region_code salió de comuna_code. No lo mandes tú: se deriva, y mandarlo no lo cambia.
address_source quedó en "manual" porque la dirección va campo por campo. La API lo estampa para distinguir una dirección que escribió una persona de una que llegó por otro camino.
display_id es B-1, y la segunda sucursal quedó como B-2. Es un identificador corto y legible que se asigna por orden de creación, para que una persona pueda nombrar la sucursal sin leer un uuid. Los endpoints que reciben {id} aceptan cualquiera de los dos.
El código de comuna
comuna_code es el código CUT oficial de cinco dígitos, no el nombre de la comuna ni el id de ningún portal. Mandarle otra cosa falla, y el mensaje te lo dice:
curl -X POST https://api.vitrinadev.com/api/v1/locations \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Sucursal Maipú", "comuna_code": "131" }'{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": {
"body": [{
"path": "comuna_code",
"message": "comuna_code must be the official 5-digit CUT code (13114 = Las Condes), never a comuna name and never a portal id",
"code": "invalid_string"
}]
},
"field_errors": {
"comuna_code": "comuna_code must be the official 5-digit CUT code (13114 = Las Condes), never a comuna name and never a portal id"
},
"requestId": "4c1e5e23-ae89-4e57-a711-5e962e8f4a8b"
}
}Fíjate en field_errors: es el mismo mensaje que details, pero ya indexado por campo, listo para pintarlo bajo el input que corresponde. Está en toda validación de cuerpo.
Omitir un campo obligatorio se ve igual:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": { "body": [{ "path": "name", "message": "Required", "code": "invalid_type" }] },
"field_errors": { "name": "Required" },
"requestId": "45c582f0-741c-4592-95bc-c2b4f679b7d2"
}
}Leer y corregir
curl https://api.vitrinadev.com/api/v1/locations/6812d9f0-9bed-44b5-91df-4e5b90941f6b \
-H "Authorization: Bearer $VITRINA_KEY"El PATCH es parcial: manda solo lo que cambia.
curl -X PATCH https://api.vitrinadev.com/api/v1/locations/6812d9f0-9bed-44b5-91df-4e5b90941f6b \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"manager_name": "Paula Riquelme",
"hours": { "lun_vie": "09:00-19:00", "sab": "10:00-14:00" }
}'{
"data": {
"id": "6812d9f0-9bed-44b5-91df-4e5b90941f6b",
"name": "Sucursal Providencia",
"manager_name": "Paula Riquelme",
"hours": { "sab": "10:00-14:00", "lun_vie": "09:00-19:00" },
"updated_at": "2026-09-15T18:34:26.470Z"
}
}hours es un objeto libre: la API lo guarda tal cual y no valida sus llaves. Elige una convención y úsala en todas tus sucursales.
Una sucursal que no existe responde 404:
{
"error": {
"code": "NOT_FOUND",
"message": "Sucursal no encontrada",
"requestId": "75a3d88b-8703-42a2-9c40-127fec0dfcc3"
}
}Desactivar
El DELETE no borra: apaga.
curl -X DELETE https://api.vitrinadev.com/api/v1/locations/094e2408-9b01-4ab6-ae65-c102a02310d1 \
-H "Authorization: Bearer $VITRINA_KEY"204, sin cuerpo. La sucursal desaparece del listado normal:
[
{ "name": "Sucursal Providencia", "display_id": "B-1", "is_active": true },
{ "name": "Sucursal Vitacura", "display_id": "B-3", "is_active": true }
]…y sigue ahí cuando la pides:
curl "https://api.vitrinadev.com/api/v1/locations?include_inactive=true" \
-H "Authorization: Bearer $VITRINA_KEY"[
{ "name": "Sucursal Providencia", "display_id": "B-1", "is_active": true },
{ "name": "Sucursal Maipú", "display_id": "B-2", "is_active": false },
{ "name": "Sucursal Vitacura", "display_id": "B-3", "is_active": true }
]Todo lo que apunta a esa sucursal (la agenda, las ventas, el catálogo) sigue apuntando a algo con nombre. Para reactivarla, PATCH con { "is_active": true }.
Trampa
Apagar una sucursal no esconde lo que apunta a ella
is_active gobierna el listado de sucursales, y nada más. Lo que ya
apuntaba a la sucursal apagada sigue ahí, sigue saliendo en sus propias
lecturas, y sigue llevando el bloque de la sucursal completo.
Tras el DELETE de arriba sobre Sucursal Maipú, un auto de esa sucursal sigue
apareciendo en GET /stock, con su bloque sucursal apuntando a la sucursal
apagada, y GET /stock?sucursal=094e2408-… sigue devolviéndolo.
Si cierras una sucursal de verdad, mueve su stock a otra o sácalo del lote
antes.