API para integraciones
Cierres
Cierres mensuales por vehículo y conductor.
En esta página
Mes de la flota o historial de un vehículo
POST/movimientos/cierres/list
- Permiso
lectura
Devuelve el mes de cada vehículo: lecturas del cuentakilómetros, resumen calculado al leer
(km de trabajo y personales, % de afectación, energía, importe justificado y coste atribuible),
estado del cierre (closeState) y semáforo (alertLevel).
Dos modos, según los campos del cuerpo:
| Modo | Cuerpo | Devuelve |
|---|---|---|
| Mes de la flota | month (+ months y vehicleId, opcionales) |
Una fila por vehículo y mes, de month y los months − 1 anteriores (months de 1 a 12, por defecto 1). Entran los vehículos activos y los dados de baja que tienen algo en ese mes (lecturas, viajes o gastos). Con vehicleId, solo ese vehículo. |
| Historial de un vehículo | vehicleId + from + to |
Todos los meses del tramo (como mucho 36), tengan o no datos. |
Orden: mes descendente y, dentro de cada mes, por matrícula. Sin paginación: la respuesta trae todas las filas del tramo (los topes de 12 y 36 meses la acotan). Un vehículo que no es de tu empresa no da error: simplemente no sale (lista vacía).
Un mes cerrado devuelve sus cifras congeladas; las de un mes abierto pueden cambiar mientras se
registren viajes, gastos o lecturas. tenantSince es el mes de alta de la empresa: un mes anterior
en el que no se registró nada no hay que cerrarlo.
Con clave API la llamada actúa como el owner que creó la clave: alcanza toda la flota de su empresa. Es solo lectura: funciona también con la cuenta en solo lectura.
Errores propios
422 invalid_input: el cuerpo no es un objeto JSON, o algún campo no es válido (fieldslos trae todos a la vez):month:required(sinmonthni historial) ·invalid.months:invalid(no es un número entero) ·out_of_range(fuera de 1..12) ·requires_month(enviado en el historial).from,to:not_with_month(junto amonth) ·required·invalid;to:before_from(anterior afrom);from:out_of_range(tramo de más de 36 meses).vehicleId:required(en el historial) ·invalid.- Cualquier otro campo:
unexpected_field.
Petición
Cuerpo obligatorio
Dos modos excluyentes: el mes de la flota (month) o el historial de un vehículo
(vehicleId + from + to).
Una de estas opciones:
CierresListFleetRequestmonthstringobligatorioÚltimo mes del tramo.
Patrón:
^[0-9]{4}-(0[1-9]|1[0-2])$Ejemplo:2026-09monthsinteger | nullmonthy losmonths − 1meses anteriores. Ausente onull: 1. Tiene que ser un número (no un texto).Mínimo
1Máximo12Por defecto:1vehicleIdinteger | string | nullSolo ese vehículo. Ausente o
null, toda la flota.integer: mínimo
1integer: máximo9007199254740991string: patrón^[1-9][0-9]{0,15}$Ejemplo:7
CierresListHistoryRequestvehicleIdinteger | stringobligatorioId (entero positivo). También se admite como texto de dígitos (
"7").integer: mínimo
1integer: máximo9007199254740991string: patrón^[1-9][0-9]{0,15}$Ejemplo:7fromstringobligatorioPrimer mes del tramo. Como mucho 36 meses hasta
to.Patrón:
^[0-9]{4}-(0[1-9]|1[0-2])$Ejemplo:2026-09tostringobligatorioÚltimo mes del tramo (igual o posterior a
from).Patrón:
^[0-9]{4}-(0[1-9]|1[0-2])$Ejemplo:2026-09
Ejemplo: Septiembre de toda la flota
curl -sS -X POST "https://app.flotadoc.com/api/movimientos/cierres/list" \
-H "Authorization: Bearer $FLOTADOC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"month": "2026-09"
}'
Otro ejemplo: Septiembre y los 5 meses anteriores de un vehículo
{
"month": "2026-09",
"months": 6,
"vehicleId": 7
}
Otro ejemplo: Historial de un vehículo durante un año
{
"vehicleId": 7,
"from": "2025-10",
"to": "2026-09"
}
Respuesta
200
Meses de los vehículos, con su resumen, estado del cierre y semáforo.
Cabeceras
X-Request-Idstring (uuid)Id de la petición en el historial de la empresa (para soporte).
dataobjectperiodsCierresVehiclePeriod[]Mes descendente y, dentro de cada mes, por matrícula.
tenantSincestring | nullMes de alta de la empresa (
YYYY-MM, hora de España).nullsi no se encuentra.Patrón:
^[0-9]{4}-(0[1-9]|1[0-2])$
Ejemplo de respuesta
{
"data": {
"periods": [
{
"vehicleId": 7,
"month": "2026-09",
"regime": "company",
"energy": "combustion",
"vehicleSince": "2026-01",
"periodId": 31,
"status": "open",
"odometerStartKm": null,
"odometerEndKm": 12000,
"previousEndKm": 10000,
"effectiveStartKm": 10000,
"totalKm": 2000,
"businessKm": 1500,
"personalKm": 500,
"professionalPct": 75,
"tripCount": 3,
"fuelTripCount": 3,
"fuelTripsKm": 1500,
"fuelLiters": 130,
"chargeKwh": 0,
"energyAmount": 200,
"energyExpenseCount": 3,
"expenseCount": 4,
"expensesWithoutTicket": 1,
"fuelPricePerLiter": 1.538,
"fuelPriceSource": "month",
"fuelPriceTicketDate": null,
"justifiedAmount": 150,
"allowanceAmount": 0,
"attributableCost": 150,
"provisionalAmount": 0,
"estimatedLiters": 97.5,
"litersDifference": 32.5,
"unconsumedTripCount": 0,
"issues": [],
"coherent": true,
"complete": true,
"closable": true,
"closedAt": null,
"closedByUserId": null,
"updatedByUserId": 10,
"updatedAt": "2026-10-01T08:00:00.000Z",
"openTrips": 0,
"warnTrips": 1,
"badTrips": 0,
"suggestedOdometerEndKm": 11950,
"suggestedOdometerSource": "expense",
"suggestedOdometerDate": "2026-09-27",
"today": "2026-10-13",
"plate": "1111AAA",
"model": "Seat León",
"vehicleActive": true,
"closeState": "with_warnings",
"alertLevel": "warn"
}
],
"tenantSince": "2026-01"
}
}
Además, las respuestas comunes: 401, 403, 404, 422, 429, 503.
Un mes de un vehículo
POST/movimientos/cierres/get
- Permiso
lectura
El mes de un vehículo: lecturas, resumen calculado al leer, estado del cierre y semáforo (el
mismo objeto que cada fila de cierres/list).
El mes se identifica por vehicleId + month; no hay id de cierre. Existe aunque nadie haya
anotado lecturas (periodId: null) y trae lo que ya se sabe (viajes, gastos y la lectura final del
mes anterior como punto de partida) con los avisos de lo que falta (issues). Un vehículo dado de
baja también se puede consultar (vehicleActive: false): es histórico fiscal.
Con clave API actúa como el owner que creó la clave, sobre cualquier vehículo de su empresa. Solo lectura.
Errores propios
404 vehicle_not_found: el vehículo no existe o no es de tu empresa (la misma respuesta en los dos casos).422 invalid_input:vehicleId,month:required·invalid; cualquier otro campo:unexpected_field.
Petición
Cuerpo obligatorio
vehicleIdinteger | stringobligatorioId (entero positivo). También se admite como texto de dígitos (
"7").integer: mínimo
1integer: máximo9007199254740991string: patrón^[1-9][0-9]{0,15}$Ejemplo:7monthstringobligatorioMes
YYYY-MM.Patrón:
^[0-9]{4}-(0[1-9]|1[0-2])$Ejemplo:2026-09
Ejemplo
curl -sS -X POST "https://app.flotadoc.com/api/movimientos/cierres/get" \
-H "Authorization: Bearer $FLOTADOC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"vehicleId": 7,
"month": "2026-09"
}'
Respuesta
200
El mes del vehículo.
Cabeceras
X-Request-Idstring (uuid)Id de la petición en el historial de la empresa (para soporte).
dataobjectperiodCierresVehiclePeriodEl mes de un vehículo: lecturas, resumen calculado al leer, estado del cierre y semáforo. Importes en euros, km con 2 decimales como mucho. Un mes cerrado trae sus cifras congeladas.
Ejemplo de respuesta
{
"data": {
"period": {
"vehicleId": 7,
"month": "2026-09",
"regime": "company",
"energy": "combustion",
"vehicleSince": "2026-01",
"periodId": 31,
"status": "open",
"odometerStartKm": null,
"odometerEndKm": 12000,
"previousEndKm": 10000,
"effectiveStartKm": 10000,
"totalKm": 2000,
"businessKm": 1500,
"personalKm": 500,
"professionalPct": 75,
"tripCount": 3,
"fuelTripCount": 3,
"fuelTripsKm": 1500,
"fuelLiters": 130,
"chargeKwh": 0,
"energyAmount": 200,
"energyExpenseCount": 3,
"expenseCount": 4,
"expensesWithoutTicket": 1,
"fuelPricePerLiter": 1.538,
"fuelPriceSource": "month",
"fuelPriceTicketDate": null,
"justifiedAmount": 150,
"allowanceAmount": 0,
"attributableCost": 150,
"provisionalAmount": 0,
"estimatedLiters": 97.5,
"litersDifference": 32.5,
"unconsumedTripCount": 0,
"issues": [],
"coherent": true,
"complete": true,
"closable": true,
"closedAt": null,
"closedByUserId": null,
"updatedByUserId": 10,
"updatedAt": "2026-10-01T08:00:00.000Z",
"openTrips": 0,
"warnTrips": 1,
"badTrips": 0,
"suggestedOdometerEndKm": 11950,
"suggestedOdometerSource": "expense",
"suggestedOdometerDate": "2026-09-27",
"today": "2026-10-13",
"plate": "1111AAA",
"model": "Seat León",
"vehicleActive": true,
"closeState": "with_warnings",
"alertLevel": "warn"
}
}
}
Además, las respuestas comunes: 401, 403, 404, 422, 429, 503.
Pendientes de cierre de la flota
POST/movimientos/cierres/pending
- Permiso
lectura
Lo que falta en la flota para cerrar month y, con months, los months − 1 anteriores (de 1 a
12, por defecto 1): vehículos sin lectura, lecturas que no cuadran, viajes en curso de meses
terminados, gastos sin ticket y meses listos para cerrar. Entran los vehículos activos y los dados
de baja con algo en el mes, como en cierres/list.
Cada fila es el mes de un vehículo (el mismo objeto que cierres/list) más sus actions, en este orden:
| Acción | Cuándo |
|---|---|
add_reading |
Mes terminado sin lectura inicial o final (closeState: missing_reading). |
fix_readings |
Lecturas que no cuadran: cuentakilómetros hacia atrás o viajes que lo superan en 1 km o más. |
finish_trips |
Mes terminado con viajes en curso (impiden cerrar). En el mes en curso, un viaje abierto es normal y no cuenta. |
attach_tickets |
Gastos sin ticket (también en el mes en curso). |
close |
El mes se puede cerrar (ready o with_warnings). |
Un mes cerrado no tiene pendientes. Un vehículo propio no se cierra, pero sus viajes abiertos y sus
gastos sin ticket sí cuentan. Las filas sin acciones no salen: con todo en orden, hasPending
es false y periods viene vacío. Orden: mes descendente y matrícula. Sin paginación.
Uso típico: un recordatorio en tu sistema a principios de mes, pidiendo el mes anterior.
Con clave API actúa como el owner que creó la clave, sobre toda su flota. Solo lectura.
Errores propios
422 invalid_input:month:required·invalid;months:invalid(no es un número entero) ·out_of_range(fuera de 1..12); cualquier otro campo:unexpected_field.
Petición
Cuerpo obligatorio
monthstringobligatorioÚltimo mes que se consulta.
Patrón:
^[0-9]{4}-(0[1-9]|1[0-2])$Ejemplo:2026-09monthsinteger | nullmonthy losmonths − 1meses anteriores. Ausente onull: 1. Tiene que ser un número (no un texto).Mínimo
1Máximo12Por defecto:1
Ejemplo
curl -sS -X POST "https://app.flotadoc.com/api/movimientos/cierres/pending" \
-H "Authorization: Bearer $FLOTADOC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"month": "2026-09",
"months": 3
}'
Respuesta
200
Pendientes del tramo de meses.
Cabeceras
X-Request-Idstring (uuid)Id de la petición en el historial de la empresa (para soporte).
dataobjectfromstringPrimer mes consultado.
Patrón:
^[0-9]{4}-(0[1-9]|1[0-2])$Ejemplo:2026-09monthstringÚltimo mes consultado.
Patrón:
^[0-9]{4}-(0[1-9]|1[0-2])$Ejemplo:2026-09hasPendingbooleantruesi alguna fila tiene acciones pendientes.totalsCierresPendingTotalsperiodsCierresPendingPeriod[]Solo los meses con alguna acción. Mes descendente y matrícula.
Ejemplo de respuesta
{
"data": {
"from": "2026-07",
"month": "2026-09",
"hasPending": true,
"totals": {
"vehicles": 1,
"missingReadings": 0,
"incoherentReadings": 0,
"openTrips": 0,
"expensesWithoutTicket": 1,
"readyToClose": 1
},
"periods": [
{
"vehicleId": 7,
"month": "2026-09",
"regime": "company",
"energy": "combustion",
"vehicleSince": "2026-01",
"periodId": 31,
"status": "open",
"odometerStartKm": null,
"odometerEndKm": 12000,
"previousEndKm": 10000,
"effectiveStartKm": 10000,
"totalKm": 2000,
"businessKm": 1500,
"personalKm": 500,
"professionalPct": 75,
"tripCount": 3,
"fuelTripCount": 3,
"fuelTripsKm": 1500,
"fuelLiters": 130,
"chargeKwh": 0,
"energyAmount": 200,
"energyExpenseCount": 3,
"expenseCount": 4,
"expensesWithoutTicket": 1,
"fuelPricePerLiter": 1.538,
"fuelPriceSource": "month",
"fuelPriceTicketDate": null,
"justifiedAmount": 150,
"allowanceAmount": 0,
"attributableCost": 150,
"provisionalAmount": 0,
"estimatedLiters": 97.5,
"litersDifference": 32.5,
"unconsumedTripCount": 0,
"issues": [],
"coherent": true,
"complete": true,
"closable": true,
"closedAt": null,
"closedByUserId": null,
"updatedByUserId": 10,
"updatedAt": "2026-10-01T08:00:00.000Z",
"openTrips": 0,
"warnTrips": 1,
"badTrips": 0,
"suggestedOdometerEndKm": 11950,
"suggestedOdometerSource": "expense",
"suggestedOdometerDate": "2026-09-27",
"today": "2026-10-13",
"plate": "1111AAA",
"model": "Seat León",
"vehicleActive": true,
"closeState": "with_warnings",
"alertLevel": "warn",
"actions": [
"attach_tickets",
"close"
]
}
]
}
}
Además, las respuestas comunes: 401, 403, 404, 422, 429, 503.
Modelos
Objetos que devuelven o reciben las operaciones de esta área. Cada campo enlaza a su modelo.
CierresVehiclePeriodobject
El mes de un vehículo: lecturas, resumen calculado al leer, estado del cierre y semáforo. Importes en euros, km con 2 decimales como mucho. Un mes cerrado trae sus cifras congeladas.
vehicleIdintegermonthstringMes
YYYY-MM.Patrón:
^[0-9]{4}-(0[1-9]|1[0-2])$Ejemplo:2026-09regimestringown: vehículo propio (se paga kilometraje);company: de empresa o renting. En un mes cerrado, el congelado al cerrar.Valores:
owncompanyenergystringEnergía actual del vehículo.
Valores:
combustionelectrichybridvehicleSincestring | nullMes de alta del vehículo (
YYYY-MM).Patrón:
^[0-9]{4}-(0[1-9]|1[0-2])$periodIdinteger | nullnull: nadie ha anotado lecturas de ese mes todavía.statusstringValores:
openclosedodometerStartKminteger | nullLectura inicial anotada en este mes (solo se usa si el mes anterior no tiene lectura final).
odometerEndKminteger | nullLectura del cuentakilómetros a fin de mes.
previousEndKminteger | nullLectura final del mes anterior (punto de partida, si existe).
effectiveStartKminteger | nullpreviousEndKmo, sin ella,odometerStartKm.totalKminteger | nullKm del cuentakilómetros (fin − inicio efectivo).
nullsi falta una lectura; negativo si va hacia atrás.businessKmnumberKm de trabajo (suma de los viajes cerrados del mes).
personalKmnumber | nulltotalKm − businessKm, nunca negativo.nullsi falta una lectura o el mes no cuadra.professionalPctnumber | null% de afectación (2 decimales).
nullsi falta una lectura o el mes no cuadra.Mínimo
0Máximo100tripCountintegerViajes cerrados del mes.
fuelTripCountintegerViajes cerrados valorados por energía (
costBasis: fuel).fuelTripsKmnumberfuelLitersnumberLitros de los tickets de combustible del mes.
chargeKwhnumberkWh de los tickets de recarga del mes.
energyAmountnumberImporte de los tickets de energía (combustible y recarga) del mes, en euros.
energyExpenseCountintegerexpenseCountintegerGastos del mes de cualquier tipo.
expensesWithoutTicketintegerfuelPricePerLiternumber | nullEuros por litro del mes (3 decimales).
nullsin ningún ticket de combustible.fuelPriceSourcestring | nullmonth: tickets del mes;last_ticket: último ticket anterior del vehículo.Valores:
monthlast_ticketfuelPriceTicketDatestring (date) | nullFecha del ticket con
last_ticket.justifiedAmountnumber | nullImporte justificado de la energía (suma de las partes de los viajes
fuel).nullsi falta una lectura o el mes no cuadra.allowanceAmountnumberKilometraje de los viajes
km_rate(vehículo propio), en euros.attributableCostnumber | nulljustifiedAmount + allowanceAmount.nullmientras el justificado esté pendiente.provisionalAmountnumberSin lectura de fin de mes, el coste de consumo de los viajes
fuel; 0 con lectura.estimatedLitersnumberLitros estimados por el consumo (l/100 km) de los viajes
fuel.litersDifferencenumberfuelLiters − estimatedLiters.unconsumedTripCountintegerViajes
fuelsin consumo (l/100 km), sin contar vehículos eléctricos.issuesstring[]Avisos del mes. Todos bloquean el cierre salvo
no_month_energy_expenses.Valores:
missing_start_readingmissing_end_readingodometer_backwardstrips_exceed_odometeropen_tripsno_month_energy_expensescoherentbooleanSin cuentakilómetros hacia atrás ni viajes que lo superen en 1 km o más.
completebooleanHay lectura inicial (efectiva) y final.
closablebooleancomplete,coherenty sin viajes en curso.closedAtstring (date-time) | nullclosedByUserIdinteger | nullupdatedByUserIdinteger | nullQuién anotó las lecturas por última vez.
updatedAtstring (date-time) | nullÚltima modificación de las lecturas o del cierre.
nullsin lecturas.openTripsintegerViajes en curso del mes.
warnTripsintegerViajes en ámbar.
badTripsintegerViajes en rojo.
suggestedOdometerEndKminteger | nullPropuesta de lectura de fin de mes (el mayor cuentakilómetros anotado en gastos o viajes del mes).
suggestedOdometerSourcestring | nullValores:
expensetripsuggestedOdometerDatestring (date) | nulltodaystring (date)Hoy en España según el servidor (con él se decide el estado del cierre).
platestringMatrícula.
modelstring | nullvehicleActivebooleanfalsesi el vehículo está dado de baja.closeStatestringEstado del cierre, decidido en este orden:
not_applicable(vehículo propio, o mes anterior al alta sin nada registrado) ·closed·in_progress(mes en curso o futuro) ·missing_reading(mes terminado sin lectura inicial o final) ·blocked(el cuentakilómetros no cuadra o queda un viaje en curso) ·with_warnings(se puede cerrar; hay gastos sin ticket o viajes en ámbar) ·ready.Valores:
not_applicableclosedin_progressmissing_readingblockedwith_warningsreadyalertLevelstringSemáforo del vehículo en el mes.
bad: algún viaje en rojo,missing_readingoblocked.warn: gastos sin ticket, viajes en ámbar o, desde el día 28 del mes en curso, la lectura de fin de mes que aún falta.ok: el resto.Valores:
okwarnbad
CierresPendingTotalsobject
vehiclesintegerVehículos distintos con algo pendiente.
missingReadingsintegerMeses con
add_reading.incoherentReadingsintegerMeses con
fix_readings.openTripsintegerViajes en curso de los meses con
finish_trips.expensesWithoutTicketintegerGastos sin ticket de los meses con
attach_tickets.readyToCloseintegerMeses con
close.
CierresPendingPeriodobject
El mes del vehículo más sus acciones pendientes.
Incluye todos los campos de CierresVehiclePeriod.
actionsstring[]En este orden fijo; solo las que aplican.
Al menos 1 elementoValores:
add_readingfix_readingsfinish_tripsattach_ticketsclose
¿Quieres conectar tu sistema?
Cuéntanos qué quieres integrar y lo vemos en una llamada: qué datos necesitas, con qué permisos y cada cuánto.
Si tu empresa ya usa FlotaDoc, el titular puede pedir el acceso desde la web, en Mi cuenta › Integraciones.