Autenticación
La API usa un token estático de empresa, no OAuth. Se envía en el encabezado Authorization tal cual, sin el prefijo Bearer.
Authorization: {{tu_api_token}}
Content-Type: application/json
El token se genera y rota desde Administración → Empresa → Token API. Es único por instalación de SIMA: todas las llamadas de una empresa usan el mismo token.
Rotar el token invalida de inmediato las integraciones que usen el anterior. Avisa a todos los consumidores de la API antes de regenerarlo.
Formato de respuesta
Todas las respuestas son JSON con la misma envoltura: un booleano de éxito, un mensaje legible y los datos.
{
"success": true,
"message": "Clientes encontrados",
"data": [ /* … */ ],
"pagination": { /* ver abajo */ }
}
{
"success": false,
"message": "Error de validación",
"errors": {
"referencia_id": [
"La referencia indicada no existe."
]
}
}
Paginación
Los endpoints de listado aceptan per_page (máximo 100) y devuelven un bloque pagination.
{
"current_page": 1,
"per_page": 25,
"total": 143,
"last_page": 6
}
Sandbox
Arma una petición real contra tu servidor: elige un endpoint, completa los parámetros y copia el código en el lenguaje que uses. Los valores quedan guardados solo en tu navegador.
Este panel genera código y una respuesta de ejemplo; no ejecuta la petición desde aquí (el navegador de esta vista no puede llamar a servidores externos). Copia el snippet y córrelo en tu terminal, Postman o tu propio backend.
Endpoints
Tres grupos de recursos: clientes (referencias), órdenes de servicio técnico y recibos de caja. Cada uno incluye ejemplos en cURL, Python, PHP y JavaScript.
| Query param | Tipo | Descripción |
|---|---|---|
| search | string | Búsqueda general por referencia, nombre o documento. |
| numero_documento | string | Documento exacto del suscriptor. |
| nombres | string | Nombre del suscriptor (parcial). |
| telefono | string | Celular del suscriptor (parcial). |
| estado_contrato_id | int | ID del estado del contrato. |
| oficina_id | int | ID de la oficina. |
| per_page | int | Default 25, máximo 100. |
{
"id": 142,
"referencia": "MED0142",
"estado_contrato": { "id": 1, "nombre": "ACTIVO" },
"suscriptor": {
"nombre_completo": "Ana María Ríos",
"numero_documento": "10234567",
"celular1": "3001234567",
"email": "ana@correo.com"
},
"inmueble": { "direccion": "Cra 10 # 20-30", "municipio": "Medellín" },
"servicios_activos": [ { "valor_mes_bruto": 89000 } ]
}
{referencia} es el código de referencia del cliente (ej. MED0142), no el ID numérico. Incluye documentos del suscriptor, contrato y las últimas 5 órdenes de servicio técnico.
Subconjunto liviano de datos usado por integraciones que solo necesitan estrato y fechas de causación/instalación.
{
"referencia": "MED0142",
"estrato": 3,
"estrato_descripcion": "Estrato 3",
"mes_causacion": "2026-09-01",
"fecha_instalacion": "2024-03-12"
}
Consultar siempre antes de crear una orden: entrega los IDs válidos de estados y tipos de servicio activos.
{
"estados_servicio": [ { "id": 1, "nombre": "REGISTRADA, PENDIENTE" } ],
"tipos_servicio_tecnico": [
{ "id": 1, "codigo": "REV", "descripcion": "Revisión técnica", "tiempo_minutos": 60 }
],
"prioridades": ["ALTA", "MEDIA ALTA", "NORMAL", "BAJA"],
"dificultades": ["NORMAL", "ALTA", "BAJA"]
}
| Query param | Tipo | Descripción |
|---|---|---|
| referencia | string | Código de referencia del cliente. |
| estado_servicio_id | int | ID del estado de la orden. |
| empleado_id | int | Técnico asignado. |
| oficina_id | int | Oficina de registro. |
| fecha_desde / fecha_hasta | date | Formato YYYY-MM-DD, filtra por fecha concertada. |
| prioridad | string | ALTA · MEDIA ALTA · NORMAL · BAJA |
| per_page | int | Default 25, máximo 100. |
{id} es el ID numérico de la orden. Incluye cliente, tipo de servicio, estado, técnico responsable y oficina.
| Campo (body) | Tipo | Descripción |
|---|---|---|
| referencia_id | int, requerido | ID numérico del cliente (no el código de referencia). |
| tipo_servicio_tecnico_id | int, requerido | Debe existir en el catálogo de tipos. |
| estado_servicio_id | int, requerido | Debe existir en el catálogo de estados. |
| fecha_inicial_concertada | datetime, requerido | YYYY-MM-DD HH:mm:ss |
| fecha_concertada_servicio | datetime, opcional | Debe ser ≥ a la fecha inicial. Si se omite, usa la inicial. |
| oficina_registro | int, opcional | Si se omite, se toma la oficina del cliente. |
| empleado_id | int, opcional | Si se omite, se asigna automático según el tipo de servicio y el responsable configurado en la oficina. |
| prioridad | string, opcional | ALTA · MEDIA ALTA · NORMAL · BAJA — default NORMAL. |
| dificultad | string, opcional | NORMAL · ALTA · BAJA — default NORMAL. |
| observaciones | string, opcional | Máximo 2000 caracteres. |
{
"success": true,
"message": "Orden de servicio creada exitosamente",
"data": {
"id": 5821,
"codigo": "OS-MED-005821",
"estado": { "nombre": "REGISTRADA, PENDIENTE" },
"empleado_responsable": { "nombre": "Carlos Pérez" }
}
}
El código de la orden se genera con el mismo algoritmo por oficina que usa la interfaz web, y si no se envía empleado_id, se resuelve el responsable según el campo configurado en la oficina para ese tipo de servicio (internet, TV, redes, etc.).
| Query param | Tipo | Descripción |
|---|---|---|
| numero_recibo | string | Código exacto del recibo. |
| referencia | string | Código de referencia del cliente. |
| numero_documento | string | Documento del suscriptor. |
| pasarela_codigo | string | Código de la pasarela de pago. |
| medio_pago | string | Nombre del medio de pago. |
| comprobante_externo | string | Comprobante de la plataforma externa. |
| revisado | bool | true / false. |
| fecha_desde / fecha_hasta | date | Formato YYYY-MM-DD. |
| per_page | int | Default 50. |
{
"id": 88213,
"numero_recibo": "REC-2026-001234",
"valor": 89000,
"iva": 0,
"revisado": false,
"estado": "Pendiente",
"fecha_hora_pago": "27/09/2026 14:32:10",
"suscriptor": { "nombre_completo": "Ana María Ríos" },
"referencia": { "referencia": "MED0142" },
"formas_pago": [ { "medio_pago": "Transferencia", "valor_pagado": 89000 } ]
}
Sin cuerpo en la petición. Es idempotente: si ya estaba revisado, responde 200 sin cambiar nada.
{
"success": true,
"message": "Recibo marcado como revisado",
"data": { "id": 88213, "revisado": true }
}
Códigos de estado
| Código | Cuándo ocurre |
|---|---|
| 200 | Petición exitosa (consulta o actualización). |
| 201 | Recurso creado — solo en POST /ordenes-servicio. |
| 401 | El servidor no tiene un API_TOKEN configurado. |
| 403 | El token enviado en Authorization no coincide con el configurado. |
| 404 | Cliente, orden o recibo no encontrado. |
| 422 | Error de validación del body — revisar errors en la respuesta. |
| 500 | Error inesperado del servidor — revisar el campo error en la respuesta. |
Flujo de ejemplo: agendar soporte técnico
Caso típico de integración: un sistema externo (por ejemplo un chatbot o un IVR) recibe el documento de un cliente y agenda una visita técnica.
GET /clientes?numero_documento=10234567 — verificar que estado_contrato.nombre == "ACTIVO".GET /ordenes-servicio/catalogos — elegir el tipo_servicio_tecnico_id correcto (ej. código REV).POST /ordenes-servicio con el id numérico del cliente encontrado en el paso 1 como referencia_id.codigo y empleado_responsable — suficientes para confirmar la visita.import requests from datetime import datetime, timedelta HEADERS = {"Authorization": API_TOKEN, "Content-Type": "application/json"} BASE = "https://tu-dominio.com/api/v1" # 1. Buscar cliente activo r = requests.get(f"{BASE}/clientes", headers=HEADERS, params={"numero_documento": "10234567"}) cliente = r.json()["data"][0] assert cliente["estado_contrato"]["nombre"] == "ACTIVO" # 2. Elegir tipo de servicio tipos = requests.get(f"{BASE}/ordenes-servicio/catalogos", headers=HEADERS).json()["data"]["tipos_servicio_tecnico"] tipo = next(t for t in tipos if t["codigo"] == "REV") # 3. Crear la orden visita = datetime.now() + timedelta(days=2) r = requests.post(f"{BASE}/ordenes-servicio", headers=HEADERS, json={ "referencia_id": cliente["id"], "tipo_servicio_tecnico_id": tipo["id"], "estado_servicio_id": 1, "fecha_inicial_concertada": visita.strftime("%Y-%m-%d %H:%M:%S"), "observaciones": "Cliente sin servicio. ONU en rojo.", }) orden = r.json()["data"] print(orden["codigo"], orden["empleado_responsable"]["nombre"])