Con tu propia API Key puedes dar de alta y listar sucursales y puntos de venta de tu empresa. No necesitas esperar al equipo CUCU ni una llave de administrador: la API resuelve el tenant dueño del recurso y solo te deja operar sobre lo tuyo.
El alta de tenant y company sigue siendo una operación administrativa de CUCU (nivel plataforma).
Este flujo self-service cubre lo que administras día a día: sucursales y puntos de venta.
Modelo de acceso
Todos los endpoints viven bajo /api/v1/admin/onboarding. El acceso a los de sucursales y POS se concede por cualquiera de estos tres caminos:
| Acceso | Alcance |
|---|
| OIDC (Keycloak) — admin | Cualquier recurso (producción interna) |
| API Key de admin tenant | Cualquier recurso |
| Tu API Key (tenant dueño) | Solo los recursos de tu propia empresa |
Anti-IDOR. La API resuelve el tenant dueño de la sucursal/POS y solo autoriza si coincide con
el de tu key. Si intentas operar sobre un recurso de otra empresa recibes 403 Forbidden. Un recurso
inexistente también responde 403 (no 404) con tu key de tenant, para no filtrar su existencia.
Jerarquía
Tenant → Company → Branch (sucursal) → POS (punto de venta)
└─ siatCode 0 = Casa Matriz
Al crear una sucursal se genera automáticamente su POS por defecto (siatCode = 0, “POS Principal”). Los POS adicionales se registran ante el SIAT en el momento de crearlos.
Crear sucursal
POST /api/v1/admin/onboarding/companies/{companyId}/branches
Crea una sucursal y su POS por defecto (siatCode = 0).
| Parámetro | Ubicación | Tipo | Req | Descripción |
|---|
X-API-Key | Header | string | Sí | Tu API Key |
companyId | Path | UUID | Sí | UUID de tu empresa |
name | Body | string | Sí | Nombre de la sucursal |
address | Body | string | Sí | Dirección |
siatCode | Body | integer | No | Código de sucursal en SIAT. Si se omite, se asigna el siguiente disponible |
city | Body | string | No | Ciudad |
municipality | Body | string | No | Municipio |
phone | Body | string | No | Teléfono |
email | Body | string | No | Email |
curl -X POST https://sandbox.cucu.bo/api/v1/admin/onboarding/companies/COMPANY_ID/branches \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"name": "Sucursal Sur",
"address": "Av. Ejemplo #123",
"city": "La Paz"
}'
const response = await fetch(
'https://sandbox.cucu.bo/api/v1/admin/onboarding/companies/COMPANY_ID/branches',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'YOUR_API_KEY'
},
body: JSON.stringify({
name: 'Sucursal Sur',
address: 'Av. Ejemplo #123',
city: 'La Paz'
})
}
);
import requests
response = requests.post(
'https://sandbox.cucu.bo/api/v1/admin/onboarding/companies/COMPANY_ID/branches',
headers={
'Content-Type': 'application/json',
'X-API-Key': 'YOUR_API_KEY'
},
json={
'name': 'Sucursal Sur',
'address': 'Av. Ejemplo #123',
'city': 'La Paz'
}
)
{
"success": true,
"message": "Branch creada con POS por defecto",
"data": {
"id": "770e8400-e29b-41d4-a716-446655440010",
"siatCode": 1,
"name": "Sucursal Sur",
"isMainOffice": false,
"address": "Av. Ejemplo #123",
"city": "La Paz",
"defaultPos": {
"id": "770e8400-e29b-41d4-a716-446655440011",
"siatCode": 0,
"name": "POS Principal",
"configured": true,
"online": true
}
}
}
Listar sucursales
GET /api/v1/admin/onboarding/companies/{companyId}/branches
Lista las sucursales de tu empresa.
| Parámetro | Ubicación | Tipo | Req | Descripción |
|---|
X-API-Key | Header | string | Sí | Tu API Key |
companyId | Path | UUID | Sí | UUID de tu empresa |
curl https://sandbox.cucu.bo/api/v1/admin/onboarding/companies/COMPANY_ID/branches \
-H "X-API-Key: YOUR_API_KEY"
Crear punto de venta
POST /api/v1/admin/onboarding/branches/{branchId}/pos
Crea un punto de venta y lo registra ante el SIAT (registrarPuntoVenta). Requiere que la company tenga token SIAT configurado y que la sucursal tenga su POS por defecto (siatCode = 0).
| Parámetro | Ubicación | Tipo | Req | Descripción |
|---|
X-API-Key | Header | string | Sí | Tu API Key |
branchId | Path | UUID | Sí | UUID de la sucursal |
name | Body | string | Sí | Nombre del punto de venta |
description | Body | string | No | Descripción (default: el name) |
siatTypePos | Body | integer | No | Tipo de POS SIAT (default: 5) |
online | Body | boolean | No | true si opera en línea (default: true) |
curl -X POST https://sandbox.cucu.bo/api/v1/admin/onboarding/branches/BRANCH_ID/pos \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"name": "Caja 2",
"description": "Caja rápida - planta baja"
}'
const response = await fetch(
'https://sandbox.cucu.bo/api/v1/admin/onboarding/branches/BRANCH_ID/pos',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'YOUR_API_KEY'
},
body: JSON.stringify({
name: 'Caja 2',
description: 'Caja rápida - planta baja'
})
}
);
import requests
response = requests.post(
'https://sandbox.cucu.bo/api/v1/admin/onboarding/branches/BRANCH_ID/pos',
headers={
'Content-Type': 'application/json',
'X-API-Key': 'YOUR_API_KEY'
},
json={
'name': 'Caja 2',
'description': 'Caja rápida - planta baja'
}
)
{
"success": true,
"message": "Punto de venta creado y registrado en SIAT",
"data": {
"id": "770e8400-e29b-41d4-a716-446655440012",
"siatCode": 2,
"name": "Caja 2",
"configured": true,
"online": true
}
}
Si el SIAT asigna un codigoPuntoVenta distinto al correlativo local, la API sincroniza el
siatCode del POS automáticamente en la respuesta.
Listar puntos de venta
GET /api/v1/admin/onboarding/branches/{branchId}/pos
curl https://sandbox.cucu.bo/api/v1/admin/onboarding/branches/BRANCH_ID/pos \
-H "X-API-Key: YOUR_API_KEY"
Marcar POS como configurado
PUT /api/v1/admin/onboarding/pos/{posId}/configure
Marca un punto de venta como listo para facturar (configured = true), tras sincronizar CUIS/CUFD y catálogos.
curl -X PUT https://sandbox.cucu.bo/api/v1/admin/onboarding/pos/POS_ID/configure \
-H "X-API-Key: YOUR_API_KEY"
Sincronizar POS desde SIAT
POST /api/v1/admin/onboarding/branches/{branchId}/sync-pos
Replica en CUCU los puntos de venta que el SIAT ya tiene registrados para esa sucursal (por ejemplo, POS creados en la Oficina Virtual del SIN). Ideal para clientes multi-sector o migraciones. Requiere el POS por defecto (siatCode = 0) de la sucursal.
curl -X POST https://sandbox.cucu.bo/api/v1/admin/onboarding/branches/BRANCH_ID/sync-pos \
-H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"message": "Sincronización completada",
"data": {
"synced": 2,
"skipped": 1,
"remoteTotal": 3,
"details": [
{ "codigoPuntoVenta": 0, "status": "exists", "id": "..." },
{ "codigoPuntoVenta": 1, "status": "created", "id": "...", "name": "Caja 1" },
{ "codigoPuntoVenta": 2, "status": "created", "id": "...", "name": "Caja 2" }
]
}
}
Estos endpoints tocan el SIAT (registrarPuntoVenta, consultarPuntosVenta) y pueden responder
502 si el SIAT rechaza o no responde. La creación de sucursales y el listado son operaciones locales.