DOCUMENTACIÓN · API ACTUAL
Integra tu jornada
Autenticación, consultas y fichajes con ejemplos listos para adaptar.
Conectar con Jinchu
Referencia de la API utilizada por /mobile/ y /mobile_p/. Esta ayuda está en /api/1/help/; los endpoints están en /api/1/.
URL base de esta instalación:
https://www.itchy.cat/lluis/jinchu/api/1Usa HTTPS y peticiones POST con application/x-www-form-urlencoded. Los datos de respuesta son JSON. Los ejemplos son ilustrativos: sustituye usuarios, contraseñas, tokens, identificadores y fechas por los de tu instalación.
Esta página solo muestra documentación: no realiza peticiones ni registra fichajes.
Formato y autenticación
El servidor lee campos de formulario. No interpreta un cuerpo JSON ni un token enviado como Authorization: Bearer. Aunque el lector común admite parámetros GET, usa POST y evita credenciales en URLs.
| Campo | Uso |
|---|---|
| user | En login: usuario de acceso. Después: conserva exactamente el user devuelto por login; no lo sustituyas por trabajador_id. |
| pass | Contraseña; solo en login y operaciones de contraseña. |
| token | Token devuelto por login. Enviarlo en cada operación autenticada. |
| company_id | Empresa devuelta por login. En cada operación autenticada. |
| canal | API para integraciones; MOVIL para la app móvil; TERMINAL para terminal presencial. También existen WEB y PWA. Debe estar permitido por la política del trabajador. |
| origen | presencial en login de un terminal (cuenta usuario/master). |
No es necesario enviar la cookie del dashboard. Conserva la sesión devuelta por login, sin registrar el token en logs ni incluirlo en el código del cliente. Si la sesión deja de ser válida, vuelve a autenticarte. El contrato actual no proporciona un endpoint de refresh ni un campo expires_in.
Respuestas y errores
{
"respuesta": { "mensaje": "Ejemplo de respuesta" },
"error": false
}Comprueba tanto el estado HTTP como error. Un error de negocio puede llegar con HTTP 200. La forma de respuesta depende del endpoint; no todos incluyen mensaje.
{
"respuesta": { "mensaje": "No hay jornada abierta" },
"error": true
}Trata los mensajes como texto para mostrar, no como códigos estables: pueden estar traducidos. Cuando existan, utiliza indicadores como fuera_horario, pide_hora_salida, canal_no_permitido, definir_password o reset_password.
Si se corta una petición de escritura, consulta el estado antes de repetirla. No hay una clave de idempotencia aportada por el cliente documentada en estos endpoints; no reintentes fichajes automáticamente.
Primeros pasos con cURL
Ejemplo para Bash con curl y jq. Este bloque inicia sesión y consulta el estado; no ficha.
BASE='https://www.itchy.cat/lluis/jinchu/api/1'
read -r -p 'Usuario: ' LOGIN_USER
read -r -s -p 'Contraseña: ' LOGIN_PASS
printf '\n'
LOGIN=$(curl --silent --show-error --fail-with-body \
"$BASE/login.php" \
--data-urlencode "user=$LOGIN_USER" \
--data-urlencode "pass=$LOGIN_PASS" \
--data-urlencode 'canal=API')
unset LOGIN_PASS
if ! printf '%s' "$LOGIN" | jq -e '.error == false and (.respuesta.token | type == "string" and length > 0)' >/dev/null; then
printf '%s' "$LOGIN" | jq '.respuesta'
exit 1
fi
API_USER=$(printf '%s' "$LOGIN" | jq -r '.respuesta.user')
API_TOKEN=$(printf '%s' "$LOGIN" | jq -r '.respuesta.token')
COMPANY_ID=$(printf '%s' "$LOGIN" | jq -r '.respuesta.company_id')
unset LOGIN
jinchu() {
local endpoint="$1"
shift
curl --silent --show-error --fail-with-body "$BASE/$endpoint" \
--data-urlencode "user=$API_USER" \
--data-urlencode "token=$API_TOKEN" \
--data-urlencode "company_id=$COMPANY_ID" \
--data-urlencode 'canal=API' "$@"
}
jinchu estadoJornada.php | jq .Login devuelve tipo, user, token, company_id, company_name y datos del trabajador. Si devuelve definir_password=1, todavía no hay sesión: define la contraseña y conserva la sesión de la respuesta correspondiente.
Flujo de jornada
- Autentica una cuenta de trabajador.
- Consulta
estadoJornada.phpy sus indicadorespuede_iniciar,puede_salida,puede_retornoypuede_terminar. - Obtén el centro y los tipos de salida. Aplica las condiciones de ubicación y horario.
- Ejecuta una acción autorizada por el usuario y comprueba la respuesta.
- Actualiza el estado. Si hay una salida abierta, registra primero el retorno antes de finalizar.
Los siguientes comandos modifican datos reales cuando se ejecutan con una sesión válida. Ejecútalos individualmente, solo para la acción deseada. Usan la función jinchu del bloque anterior.
# Consultas
jinchu getCentros.php | jq .
jinchu getTiposSalida.php | jq .
# Iniciar (sustituye el centro por un ID válido)
jinchu iniciarJornada.php --data-urlencode 'centro_id=123' | jq .
# Salir (tipo_id procede de getTiposSalida.php)
jinchu salida.php --data-urlencode 'tipo_id=456' --data-urlencode 'centro_id=123' | jq .
# Volver de la salida
jinchu retorno.php --data-urlencode 'centro_id=123' | jq .
# Finalizar sin salidas pendientes
jinchu terminarJornada.php --data-urlencode 'centro_id=123' | jq .
# Historial mensual
jinchu getJornadasTrabajador.php --data-urlencode 'mes=2026-09' | jq .computa_trabajo=1 identifica una salida cuyo tiempo cuenta como trabajo. Los resúmenes de jornada incluyen ese tiempo. Los marcajes usan I (inicio), S (salida), R (retorno) y T (final).
Ubicación, centro y horario
| Campo | Descripción |
|---|---|
| centro_id | ID de un centro activo. La obligatoriedad depende del contexto y de la política. |
| latitud / longitud | Coordenadas reales del dispositivo, en grados decimales. |
| precision_metros | Precisión real de la lectura de ubicación, en metros. |
| fecha_hora_cliente | Fecha/hora informativa del cliente. No reemplaza el reloj del servidor. |
| confirmar_fuera_horario | 1 solo después de aceptar explícitamente el flujo fuera de horario. |
| fecha_hora | Fecha/hora local YYYY-MM-DD HH:mm:ss para correcciones y el cierre fuera de horario cuando se solicita. |
| justificacion | Texto explicativo para incidencias; el servidor limita su longitud a 500 caracteres. |
El estado expone la política de ubicación. Si es obligatoria, obtén una lectura válida y consulta getCentrosCercanos.php con latitud y longitud. No inventes coordenadas. Los centros devueltos no sustituyen la validación que se realiza al fichar.
Fuera de horario, el servidor puede responder error=true y fuera_horario=1. Muestra el mensaje y solicita la intervención del usuario. En el cierre puede pedir también fecha_hora. No añadas confirmar_fuera_horario=1 indiscriminadamente: confirma un flujo que puede generar una incidencia.
Las fechas declaradas son locales a la zona de la empresa/sesión. Los marcajes almacenan también la hora UTC del servidor. No envíes una fecha local como si fuera UTC.
Referencia de endpoints
Todos se llaman bajo /api/1/ y admiten el formato POST descrito. «Sesión» implica user, token y company_id. «Trabajador» exige una cuenta asociada a un trabajador; «Usuario/master» exige cuenta general.
| Endpoint | Acceso | Parámetros adicionales | Resultado / uso |
|---|---|---|---|
| login.php | Sin sesión | user, pass, canal; origen=presencial para terminal | Sesión o indicador de definición de contraseña |
| estadoJornada.php | Sesión | — | Estado, permisos de acciones, política, salidas y ultima |
| getCentros.php | Sesión | — | centros[] |
| getCentrosCercanos.php | Trabajador | latitud, longitud | centros[] y política |
| getTiposSalida.php | Sesión | — | tipos[] con computa_trabajo |
| getTiposIncidencia.php | Sesión | — | Alias actual de getTiposSalida.php |
| getIncidenciasJustificaciones.php | Sesión | — | justificaciones[] |
| iniciarJornada.php | Trabajador | Centro/ubicación según política | Abre jornada; devuelve estado |
| salida.php | Trabajador | tipo_id; centro/ubicación según política | Abre salida; devuelve estado |
| retorno.php | Trabajador | Centro/ubicación según política | Cierra salida; devuelve estado |
| terminarJornada.php | Trabajador | Centro/ubicación; campos fuera de horario si se solicitan | Cierra jornada; devuelve estado |
| cambiarCentro.php | Trabajador | centro_id; ubicación según política | Cambia el centro de la jornada abierta |
| getJornadasTrabajador.php | Sesión | mes YYYY-MM o fecha YYYY-MM-DD; trabajador_id para usuario/master | jornadas[] y resumen; el mes incluye semanas completas limítrofes hasta hoy |
| getJornadaTrabajador.php | Usuario/master | trabajador_id | Última jornada trabajada en jornada (puede ser null) |
| getTrabajadores.php | Usuario/master | centro_id opcional | trabajadores[]; con centro_id filtra por la asignación vigente para hoy. Si el centro tiene una asignación Todos vigente, incluye a todos los trabajadores activos con el canal permitido, aunque estén asignados individualmente a otro centro. Se excluyen los que tienen una jornada abierta cuyo centro efectivo actual es otro. |
| nuevaIncidencia.php | Trabajador | ambito, fecha_hora, jornada_id; salida_id para salida/retorno; justificacion | Solicitud/corrección según política |
| definirPassword.php | Sin sesión | user, pass, pass2 | Solo si el trabajador no tiene contraseña definida; devuelve sesión |
| cambiarPassword.php | Sesión de trabajador | pass_actual, pass, pass2 | Cambia contraseña; vuelve a iniciar sesión para renovar el token |
| olvidarPassword.php | Sin sesión | user, canal | Solicita restablecimiento mediante incidencia |
Incidencias de hora: ambito puede ser INICIAR, SALIDA, RETORNO o TERMINAR. INICIO_ERROR tiene un flujo específico para un inicio erróneo. Usa identificadores obtenidos de la jornada; la API comprueba propiedad, fechas y condiciones de aprobación.
Terminal presencial
Autentica una cuenta general con origen=presencial y canal=TERMINAL. Conserva sus credenciales de sesión. Para actuar sobre un trabajador envía además trabajador_id, centro_id y su pin de cuatro dígitos. El canal TERMINAL debe estar permitido.
| Endpoint | Uso / campos |
|---|---|
| getJornadaPresencial.php | Consultar estado con PIN. |
| iniciarJornadaPresencial.php | Iniciar jornada con PIN. |
| salidaJornadaPresencial.php | Registrar salida con PIN y tipo_id. |
| retornoJornadaPresencial.php | Registrar retorno con PIN. |
| terminarJornadaPresencial.php | Finalizar con PIN; aplica flujo fuera de horario. |
| nuevaIncidenciaPresencial.php | PIN y campos de incidencia equivalentes al flujo de trabajador. |
| definirPinPresencial.php | Sesión general + trabajador_id + centro_id + pin nuevo; solo si aún no tiene PIN. |
| cambiarPinPresencial.php | PIN actual en pin; nuevo en pin_nuevo. |
| olvidarPinPresencial.php | Sesión general + trabajador_id + centro_id, sin exigir PIN; solicita reinicio por incidencia. |
# Con las credenciales de la cuenta general, no las de un trabajador:
curl --silent --show-error --fail-with-body "$BASE/getJornadaPresencial.php" \
--data-urlencode "user=$API_USER" \
--data-urlencode "token=$API_TOKEN" \
--data-urlencode "company_id=$COMPANY_ID" \
--data-urlencode 'canal=TERMINAL' \
--data-urlencode 'trabajador_id=123' \
--data-urlencode 'centro_id=456' \
--data-urlencode 'pin=0000'El PIN del ejemplo es ficticio. Manténlo como texto para conservar ceros iniciales.
JavaScript · fetch
Ejemplo desde una página del mismo origen que Jinchu. Si lo ejecutas desde otro dominio, necesitas una configuración CORS del servidor; esta documentación no habilita CORS. No uses mode: no-cors para intentar leer la respuesta.
const base = new URL('../../1/', window.location.href).href; // Desde /api/1/help/
async function request(endpoint, fields) {
const response = await fetch(base + endpoint, {
method: 'POST',
body: new URLSearchParams(fields),
credentials: 'omit',
cache: 'no-store'
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const result = await response.json();
if (result.error || !result.respuesta) {
throw new Error(result.respuesta?.mensaje || 'Error de API');
}
return result.respuesta;
}
// Llamar desde el envío del formulario de acceso:
async function consultarMiJornada(user, pass) {
const session = await request('login.php', { user, pass, canal: 'API' });
if (!session.token) throw new Error('Completa la definición de contraseña');
const auth = {
user: session.user,
token: session.token,
company_id: session.company_id,
canal: 'API'
};
const estado = await request('estadoJornada.php', auth);
return { auth, estado }; // No mostrar ni registrar auth en logs
}Python · requests
Instala la dependencia con python -m pip install requests. Este ejemplo solo autentica y consulta.
import getpass
import requests
BASE = "https://www.itchy.cat/lluis/jinchu/api/1"
def request(endpoint, fields):
response = requests.post(f"{BASE}/{endpoint}", data=fields, timeout=25)
response.raise_for_status()
result = response.json()
if result.get("error") or "respuesta" not in result:
raise RuntimeError(result.get("respuesta", {}).get("mensaje", "Error de API"))
return result["respuesta"]
session = request("login.php", {
"user": input("Usuario: "),
"pass": getpass.getpass("Contraseña: "),
"canal": "API",
})
if not session.get("token"):
raise RuntimeError("Completa la definición de contraseña")
auth = {key: session[key] for key in ("user", "token", "company_id")}
auth["canal"] = "API"
estado = request("estadoJornada.php", auth)
print("Trabajando:", estado.get("trabajando"))
print("Tiempo:", estado.get("tiempo"))Postman / Insomnia
- Crea una petición POST a la URL base más
/login.php. - En Body elige x-www-form-urlencoded y añade user, pass y canal=API.
- Envía la petición y guarda user, token y company_id de respuesta como variables privadas de tu entorno.
- En las siguientes peticiones añade esos tres campos y canal al formulario. No uses Bearer Token.
- Consulta primero estadoJornada.php. Antes de un fichaje revisa permisos, centro, ubicación y horario.
Resolución de problemas
| Síntoma | Qué comprobar |
|---|---|
| Sesión no válida | Envía los tres campos de sesión y conserva el user devuelto por login. Vuelve a entrar si cambió la contraseña. |
| Canal no permitido | La política del trabajador debe permitir API o el canal real de tu cliente. |
| Campos obligatorios / ubicación | Verifica centro_id, coordenadas y requisitos de la operación. |
| Jornada ya abierta | Consulta estadoJornada.php; no repitas el inicio. |
| Salida sin retorno | Registra retorno antes de abrir otra salida o finalizar. |
| Fuera de horario | Gestiona el flujo explícito de confirmación/incidencia y los campos pedidos. |
| Respuesta HTML o JSON no válido | Comprueba URL, red y errores del servidor. No interpretes una respuesta ilegible como fichaje fallido seguro. |
| Timeout después de fichar | Comprueba el estado antes de reintentar; el servidor pudo haber registrado la operación. |
Esta referencia describe el código actual del repositorio. Los permisos y condiciones dependen de la configuración de cada empresa.