Errores y paginación
Esta guía describe cómo la API de Rently comunica los errores (estructura JSON y códigos), qué significan los códigos de estado HTTP más habituales, y cómo recorrer respuestas paginadas con los parámetros offset y limit.
Todos los ejemplos asumen que ya obtuviste un token Bearer. Consultá la guía de autenticación para el detalle del flujo. El header de autorización se envía en cada llamada:
Authorization: Bearer {token}
Formato de errores
Cuando una petición no puede completarse por un error de negocio o de validación, la API responde con un cuerpo JSON con la siguiente estructura:
| Campo | Tipo | Descripción |
|---|---|---|
ErrorMessage | string (nullable) | Mensaje legible que describe el error. |
ErrorCode | integer | Código numérico que identifica el tipo de error (ver tabla de códigos). |
Id | string (nullable) | Identificador de correlación para rastrear el error en soporte. |
ErrorCode se serializa siempre como número entero, no como texto. Por ejemplo, 1 corresponde a CustomerNotFound.
Ejemplo de respuesta de error
{
"ErrorMessage": "The requested resource was not found",
"ErrorCode": 1,
"Id": "0HMVB9A2K3C4D-00000001"
}
Guardá el valor de Id en tus logs. Es el identificador de correlación que permite a soporte de Rently ubicar la traza exacta de la petición que falló.
Códigos de error (ErrorCode)
El campo ErrorCode proviene de una enumeración con valores numéricos. La siguiente tabla lista todos los códigos de error que puede devolver la API:
| Code | Name | Description |
|---|---|---|
| 0 | NoError | No ocurrió ningún error. |
| 1 | CustomerNotFound | No se encontró en el sistema el cliente solicitado. |
| 2 | CarNotFound | No se encontró en el sistema el auto solicitado. |
| 3 | CarNotAvailable | El auto solicitado no está disponible para las fechas indicadas. |
| 4 | PriceMismatch | El precio calculado no coincide con el precio esperado. |
| 5 | CustomerDataNotValid | Los datos del cliente proporcionados no son válidos. |
| 6 | LanguageNotSupported | El idioma solicitado no es compatible con el sistema. |
| 7 | InsuficientPermissions | El usuario no tiene permisos suficientes para realizar la operación. |
| 8 | BookingNotFoundForCustomer | No se encontró ninguna reserva para el cliente indicado. |
| 9 | BookingStatusNotAllowCancel | El estado actual de la reserva no permite la cancelación. |
| 10 | CreditCardNotAvailable | La tarjeta de crédito no está disponible para su uso. |
| 11 | GatewayNotSupported | La pasarela de pago solicitada no es compatible. |
| 12 | InfractionNotFound | No se encontró la infracción solicitada. |
| 13 | InvlaidDates | Las fechas proporcionadas no son válidas. |
| 14 | UnquotedReserve | La reserva no fue cotizada. |
| 15 | MaxDayForQuotedReserve | Se superó la cantidad máxima de días para una reserva cotizada. |
| 21 | TariffNotFound | No se encontró el tarifario solicitado. |
| 22 | BookingNotFound | No se encontró la reserva solicitada. |
| 23 | ReturnPlaceNotFound | No se encontró el lugar de devolución indicado. |
| 24 | PromotionNotFound | No se encontró la promoción solicitada. |
| 25 | DeliveryPlaceNotFound | No se encontró el lugar de entrega indicado. |
| 26 | BookingStatusNotAllowUpdate | El estado actual de la reserva no permite actualizaciones. |
| 27 | IlimitedKmNotEnabled | La opción de kilómetros ilimitados no está habilitada. |
| 28 | LimitedKmNotEnabled | La opción de kilómetros limitados no está habilitada. |
| 29 | MinimunDaysOfBookingNotReached | No se alcanzó la cantidad mínima de días para la reserva. |
| 30 | MaxDaysOfBookingReached | Se superó la cantidad máxima de días para la reserva. |
| 31 | AdditionalNotFound | No se encontró el adicional solicitado. |
| 32 | AdditionalMaxQuantityExceeded | Se superó la cantidad máxima para el adicional. |
| 33 | DateFromForBookingNotEnabled | La fecha de inicio de la reserva no está habilitada. |
| 34 | DriverAgeNotAllowed | La edad del conductor no está dentro del rango permitido. |
| 35 | BookingVersionError | Hay una discrepancia de versión con la reserva. |
| 36 | BookingAlreadyDelivered | La reserva ya fue entregada. |
| 37 | BookingAlreadyReturned | La reserva ya fue devuelta. |
| 38 | BookingNeedsToCompleteDeposit | La reserva requiere un depósito para ser completada. |
| 39 | InvalidCarKilometers | El valor de kilómetros del auto no es válido. |
| 40 | BookingStatusNotAllowDelivery | El estado actual de la reserva no permite la entrega. |
| 41 | DriverLicenseInvalid | La licencia de conducir no es válida. |
| 42 | BookingStatusNotAllowReturn | El estado actual de la reserva no permite la devolución. |
| 43 | NotificationRelatedEntityNotFound | No se encontró la entidad relacionada de la notificación. |
| 44 | NotificationReceiverAddressInvalid | La dirección del destinatario de la notificación no es válida. |
| 45 | MailNotificationDisabled | Las notificaciones por correo están deshabilitadas. |
| 46 | ReturnPlaceNotAllowedForDeliveryPlace | El lugar de devolución no está permitido para el lugar de entrega indicado. |
| 47 | BookingOutOfOfficeHoursNotAllowed | No se permiten reservas fuera del horario de atención. |
| 48 | NotificationNotFound | No se encontró la notificación solicitada. |
| 49 | BlockedCustomerToBook | El cliente está bloqueado para realizar reservas. |
| 50 | MustHaveAtLeastOneInsurance | La configuración del sistema requiere seleccionar al menos un seguro al crear o editar una reserva. |
| 51 | InvalidCommercialAgreement | El acuerdo comercial no es válido. |
| 60 | AppProtocolNotFound | No se encontró el protocolo de la aplicación. |
| 61 | ServiceTypeInvalid | El tipo de servicio no es válido. |
| 62 | ServiceStatusInvalid | El estado del servicio no es válido. |
| 63 | ServiceDatesInvalids | Las fechas del servicio no son válidas. |
| 64 | ServiceProviderNotFound | No se encontró el proveedor del servicio. |
| 65 | ServiceCanNotCreate | No se puede crear el servicio. |
| 66 | ServiceCanNotEdit | No se puede editar el servicio. |
| 67 | ServiceNotFound | No se encontró el servicio solicitado. |
| 68 | CarLocationInvalidDriver | La ubicación del auto tiene un conductor inválido. |
| 69 | ReturnPlaceIsCurrentPlaceError | El lugar de devolución es el mismo que el lugar actual. |
| 70 | CarIsNotFree | El auto no está disponible para la operación solicitada. |
| 71 | CarTransferError | Ocurrió un error durante la transferencia del auto. |
| 72 | InvalidCarGasoline | El nivel de combustible del auto no es válido. |
| 73 | CannotDeliverBookingWithBalance | No se puede entregar una reserva con un saldo pendiente. |
| 74 | PlaceDoesNotAcceptCustomAddresses | El lugar no acepta direcciones personalizadas. |
| 75 | PlaceCantOperatesLikePickUp | El lugar no puede operar como punto de entrega. |
| 76 | PlaceCantOperatesLikeDropOff | El lugar no puede operar como punto de devolución. |
| 77 | CannotPayQuote | No se puede pagar la cotización. |
| 80 | FeatureNotEnabled | La funcionalidad solicitada no está habilitada. |
| 98 | ModelNotValid | El modelo no es válido. |
| 99 | Unknown | Ocurrió un error desconocido. |
| 100 | MissingCurrencyCode | Falta el código de moneda. |
| 101 | TotalGreaterThanZero | El monto total debe ser mayor que cero. |
| 102 | InfractionAlreadyExists | El acta de infracción o la violación ya existe en el sistema. |
| 103 | InvalidIncidentType | El tipo de incidente no es válido |
| 104 | InvalidIncidentDate | La fecha del incidente no es válida |
| 105 | SettingNotFound | No se encontró una configuración requerida |
| 106 | BookingBrandNotFound | Booking Brand no encontrado |
| 107 | BookingCannotBeUncancelled | — |
| 108 | RateAlreadyExists | Ya existe una tasa con el código dado y no se solicitaron actualizaciones. |
| 499 | Timeout | — |
| 1100 | MappingAlreadyExists | — |
| 1101 | ModelNotExists | — |
| 1102 | CompanyCodeNotFound | — |
| 1103 | CommercialAgreementNotSupported | El acuerdo comercial no es compatible. |
| 1104 | CommercialAgreementRequired | — |
| 1105 | InfractionNoticeNotFound | El Aviso de Infracción referenciado no se encontró para el inquilino. |
| 1106 | InfractionNoticeDismissed | El Aviso de Infracción referenciado queda desestimado y no puede ser vinculado. |
| 1107 | InfractionNoticeContextMismatch | El contexto de la infracción (coche, fecha, reserva o conductor) no coincide con el Aviso de Infracción. |
| 1108 | InfractionNoticeMainAlreadyLinked | El Aviso de Infracción ya incluye una infracción principal vinculada. |
| 1109 | InfractionNoticeNicAlreadyLinked | El InfractionNotice ya incluye una infracción NIC (penalización por no identificación del conductor). |
| 1110 | InfractionNoticeInfractionAlreadyLinked | La infracción ya está vinculada a otro Aviso de Infracción. |
Los valores numéricos no son contiguos: la enumeración salta posiciones (por ejemplo, de 15 a 21). Mapeá tus reintentos y mensajes a partir del valor exacto y no asumas rangos correlativos.
Códigos de estado HTTP
La API utiliza un conjunto acotado de códigos de estado. Tené en cuenta que los fallos de autenticación se reportan como 403 (la API no devuelve 401).
| Estado | Significado | Cuerpo |
|---|---|---|
200 OK | La petición se procesó correctamente. | Payload del recurso o resultado paginado. |
400 Bad Request | Error de negocio o de validación (Api Error). | JSON con ErrorMessage, ErrorCode e Id. |
403 Forbidden | Usuario no autenticado o sin permisos para el endpoint. | Sin cuerpo. |
404 Not Found | El recurso solicitado no existe. | Sin cuerpo. |
Un 403 puede significar tanto que el token es inválido o ausente como que el usuario autenticado no tiene el permiso requerido para ese endpoint. Verificá primero el header Authorization y luego los permisos del usuario.
Cómo manejar errores
200→ procesá la respuesta normalmente.400→ leéErrorCodepara decidir la acción (corregir datos, recotizar, etc.) y mostráErrorMessageal operador.403→ revisá que el token sea válido, esté vigente y corresponda al mismo tenant; confirmá que el usuario tenga permisos.404→ el identificador usado no corresponde a ningún recurso; validá los IDs antes de reintentar.
Paginación
Los endpoints que devuelven listas (por ejemplo GET /api/bookings/list, GET /api/customers o GET /api/cars) usan paginación por offset y limit.
Parámetros de consulta
| Parámetro | Tipo | Default | Descripción |
|---|---|---|---|
offset | integer | 0 | Punto de partida de la página. Debe ser >= 0. |
limit | integer | 30 | Cantidad máxima de elementos por página. Se recorta a un máximo de 100. |
Si enviás un limit mayor a 100, la API lo recorta automáticamente a 100. Un offset negativo se normaliza a 0.
Forma del resultado
Las respuestas paginadas comparten la misma estructura PagedResult:
| Campo | Tipo | Descripción |
|---|---|---|
Offset | integer | Offset aplicado a esta página. |
Limit | integer | Límite aplicado a esta página. |
Total | integer | Total de elementos disponibles en todas las páginas. |
Results | array (nullable) | Elementos de la página actual. |
NextOffset | integer | Offset a usar para solicitar la página siguiente. |
Ejemplo de respuesta paginada
{
"Offset": 0,
"Limit": 30,
"Total": 2,
"Results": [
{ "Id": 1 },
{ "Id": 2 }
],
"NextOffset": 0
}
Ejemplo de request
curl "https://{tenant}.rently.com.ar/api/customers?offset=0&limit=30&language=es-AR" \
-H "Authorization: Bearer {token}"
Cómo recorrer todas las páginas
Para iterar la totalidad de un listado, usá NextOffset de cada respuesta como offset de la petición siguiente. La iteración termina cuando Results trae menos elementos que Limit.
# Página 1
curl "https://{tenant}.rently.com.ar/api/bookings/list?offset=0&limit=30&language=es-AR" \
-H "Authorization: Bearer {token}"
# Página 2: usar el NextOffset devuelto por la página anterior
curl "https://{tenant}.rently.com.ar/api/bookings/list?offset={NextOffset}&limit=30&language=es-AR" \
-H "Authorization: Bearer {token}"
Para la iteración, fijate en Results.Count < Limit como condición de fin en lugar de comparar contra Total. Esto funciona de forma consistente con ambos estilos de paginación de la API.
En GET /api/bookings/list el parámetro offset funciona como cursor por Id, no como cantidad de registros a saltar. Pasá siempre 0 en la primera llamada (sin importar la dirección de orden) y, en las siguientes, el valor de NextOffset que devolvió la respuesta anterior. No construyas el offset manualmente sumando tamaños de página.