Respuestas y errores

Contrato de respuestas y errores de Admin API

Este archivo completa el contrato de respuesta de cada endpoint de la Referencia de endpoints. Consulta en la fila del endpoint el cuerpo correcto y en las tablas siguientes todos los cuerpos compartidos o específicos de respuestas no satisfactorias. Por defecto, los errores utilizan varias estructuras de compatibilidad; los clientes pueden optar por una envoltura universal.

Envoltura de error estructurada opcional

Envía esta cabecera de solicitud a cualquier endpoint:

X-Error-Format: envelope

La comparación del valor elimina espacios de los extremos y no distingue mayúsculas de minúsculas. Con ese valor exacto, toda respuesta JSON cuyo estado sea 400 o superior se convierte en:

ErrorEnvelope = {
  error: {
    code: string,
    message: string,
    details: Record<string, unknown>,
    requestId: string
  }
}

Ejemplo de conversión de un cuerpo de validación predeterminado:

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Invalid request",
    "details": {
      "fields": {
        "name": ["String must contain at least 1 character(s)"]
      }
    },
    "requestId": "integration-42"
  }
}

Las reglas de conversión son exactas:

  • validationErrors se convierte en details.fields y code en VALIDATION_FAILED, incluso cuando el cuerpo predeterminado ya tenía un código de dominio.
  • El code de nivel superior predeterminado se conserva cuando no hay campos de validación.
  • Las demás propiedades de nivel superior, excepto error, message, validationErrors y code, se trasladan a details; por ejemplo, limit de la exportación de informes se convierte en details.limit.
  • Un error de nivel superior de tipo cadena se convierte en message. Si no existe, se utiliza el texto de respaldo del estado.
  • Los códigos de respaldo son AUTH_REQUIRED (401), PERMISSION_DENIED (403), RESOURCE_NOT_FOUND (404), CONFLICT (409), VALIDATION_FAILED (422 y otros 4xx sin clasificar), RATE_LIMITED (429), EXTERNAL_PROVIDER_FAILED (502) y INTERNAL_ERROR (otros 5xx, incluido 503).
  • requestId es la cabecera de respuesta X-Request-Id exacta. Un ID de solicitud proporcionado por el cliente solo se utiliza si coincide con [A-Za-z0-9._:-]{1,128} tras eliminar los espacios de los extremos; de lo contrario, el servidor genera un UUID.

Esta transformación no cambia el estado ni las cabeceras ajenas al cuerpo. También se aplica a las repeticiones idempotentes según la cabecera X-Error-Format de la solicitud de repetición. Las respuestas correctas binarias siguen siendo binarias; sus errores JSON se envuelven. Las tablas restantes muestran los cuerpos predeterminados; aplicar las reglas anteriores proporciona el otro cuerpo posible para cada fila.

Notación de respuestas

ValidationError = {
  validationErrors: Record<string, string[]>,
  code?: string
}

CodedError = {
  error: string,
  code: string,
  // a route may add fields explicitly listed below
}

PlainError = { error: string }

error y el texto de los mensajes de validación son descriptivos, no un discriminador programático estable. Basa la lógica en code cuando esté presente. La validación de solicitudes devuelve 422 ValidationError; validar un objeto completo puede producir { "validationErrors": {} } si no se identifica un campo individual. El JSON no válido y los fallos inesperados devuelven el 500 PlainError global mostrado a continuación.

Todos los ejemplos JSON muestran las estructuras exactas de los cuerpos. El texto indicado como <message> es el mensaje de validación u operación devuelto y es una cadena JSON, no un valor literal entre signos de menor y mayor.

Orden de procesamiento de solicitudes

Las solicitudes se procesan en este orden:

  1. configuración y autenticación de tokens de espacios de trabajo;
  2. políticas del host y límites de solicitudes del token/espacio de trabajo;
  3. filtrado según los derechos actuales;
  4. validación y reserva de idempotencia para cada modificación;
  5. comprobación de ámbitos del endpoint, validación de la solicitud y operación solicitada.

Por tanto, una solicitud de modificación con un token válido pero con ámbitos insuficientes sigue teniendo que enviar Idempotency-Key. Una respuesta de modificación completada con 403, 404, 409 o 422 se puede repetir con la misma clave y solicitud.

Respuestas de autenticación, políticas y límites de solicitudes

Estas respuestas pueden aparecer en cualquier endpoint /v2/admin registrado antes del procesamiento específico del endpoint.

EstadoCuándoCuerpo exactoCabeceras relevantes
401Token de espacio de trabajo ausente, duplicado, unido por comas, no Bearer, mal formado, desconocido, caducado, revocado o no válido por otro motivo{ "error": "Unauthorized", "code": "INVALID_WORKSPACE_TOKEN" }WWW-Authenticate: Bearer, Cache-Control: no-store
404El token es válido, pero el host de su espacio de trabajo no tiene adminApiEnabled{ "error": "Not Found" }Cache-Control: no-store
429Se ha agotado la cuota de solicitudes del token o del espacio de trabajo{ "error": "Too many attempts. Please try again later." }Retry-After: <seconds>
503La autenticación de tokens de espacios de trabajo no está disponible temporalmente{ "error": "Admin API workspace-token configuration is unavailable", "code": "WORKSPACE_API_CONFIG_UNAVAILABLE" }—
503Falla la consulta de políticas del host o la autorización de derechos actuales{ "error": "Workspace authorization is temporarily unavailable", "code": "WORKSPACE_AUTHORIZATION_UNAVAILABLE" }—

El acceso a la API está incluido en todos los planes. Desactivar el ajuste adminApiEnabled del host del espacio de trabajo devuelve 404; perder el derecho a una función adicional solo elimina los ámbitos afectados. La denegación del ámbito resultante utiliza la respuesta siguiente, no un proceso de renovación del token.

Fallos de ámbitos, idempotencia, análisis, propiedad e imprevistos

Se aplica aEstadoCuerpo exactoCabeceras/notas
Toda ruta después de la autenticación403{ "error": "Insufficient workspace-token scope", "code": "INSUFFICIENT_SCOPE" }Se devuelve cuando falta algún ámbito obligatorio.
Toda operación de modificación400{ "error": "Idempotency-Key is required for this operation", "code": "IDEMPOTENCY_KEY_REQUIRED" }No se ha proporcionado ninguna clave.
Toda operación de modificación400{ "error": "Exactly one Idempotency-Key is required", "code": "INVALID_IDEMPOTENCY_KEY" }Cabecera duplicada o valores unidos por comas.
Toda operación de modificación400{ "error": "Idempotency-Key must contain 1 to 255 visible characters", "code": "INVALID_IDEMPOTENCY_KEY" }Vacío, demasiado largo o contiene un carácter de control.
Toda operación de modificación409{ "error": "Idempotency-Key was already used with a different request", "code": "IDEMPOTENCY_CONFLICT" }Mismo token, método, ruta y clave, pero URL o cuerpo diferentes.
Toda operación de modificación409{ "error": "Request is already processing", "code": "IDEMPOTENT_REQUEST_PROCESSING" }Retry-After: 5.
Toda operación de modificación409{ "error": "Previous request outcome is unknown; verify its effects before attempting the operation again", "code": "IDEMPOTENCY_OUTCOME_UNKNOWN" }La concesión de procesamiento anterior ha caducado, la conexión se ha cerrado o la solicitud ha terminado con un 5xx.
Toda operación de modificación503{ "error": "Idempotency storage unavailable", "code": "IDEMPOTENCY_UNAVAILABLE" }La API no puede comprobar ni guardar el registro de idempotencia.
Cualquier endpoint con un esquema de consulta, cuerpo o ruta no válido422{ "validationErrors": { "<field>": ["<message>"] } }Puede haber varios campos o mensajes. Los clientes no pueden proporcionar cpoId; el espacio de trabajo siempre procede del token.
Cualquier recurso anidado del espacio de trabajo no encontrado o ID de otro espacio de trabajo404{ "error": "Workspace resource not found", "code": "RESOURCE_NOT_FOUND" }Se utiliza de forma uniforme salvo que una tabla posterior indique lo contrario.
Cualquier endpoint con un fallo inesperado500{ "error": "Something went wrong" }En las operaciones de modificación, reintentar la misma clave más adelante devuelve 409 IDEMPOTENCY_OUTCOME_UNKNOWN.

Los ID de recursos de la ruta deben ser números positivos. Un :siteId, :chargerId, :portId, :tariffId, :profileId, :assignmentId, :userId, :rfidId, :accessId, :limitId o :localUserId no positivo o no numérico devuelve 422 ValidationError, no 400.

Errores de emplazamientos y gestión de potencia

EndpointsEstadoCuerpo exacto
Creación/actualización de emplazamiento; validación de campos del espacio de trabajo422{ "validationErrors": { "<field>": ["<message>"] } }
DELETE /v2/admin/sites/:siteId cuando el emplazamiento tiene dependencias409{ "error": "<message>", "code": "SITE_NOT_EMPTY" }
GET /v2/admin/sites/geocode búsqueda normalizada no válida400{ "error": "<message>", "code": "INVALID_GEOCODE_QUERY" }
Lo mismo, cola acotada del proveedor llena429{ "error": "<message>", "code": "GEOCODING_BUSY" }; incluye Retry-After cuando lo proporciona el geocodificador
Lo mismo, tiempo de espera o fallo del proveedor o error inesperado de geocodificación502{ "error": "<message>", "code": "GEOCODING_UNAVAILABLE" }; un error inesperado utiliza Address search is temporarily unavailable
PUT /v2/admin/sites/:siteId/power-management configuración de topología/dominio no válida422{ "error": "<message>", "code": "INVALID_POWER_MANAGEMENT_CONFIGURATION" }
Lo mismo, rechazo o tiempo de espera OCPP, condición de carrera o conflicto de conciliación409{ "error": "<message>", "code": "POWER_MANAGEMENT_CONFLICT" }

Errores de cargadores

mapChargerErrors() se utiliza para crear/actualizar cargadores, credenciales, ajustes de conectores, publicación, resolución de datos QR, modificación/recarga de configuración, inicio de firmware, los cuatro comandos básicos y la solicitud de programación compuesta.

EndpointsEstadoCuerpo exacto
Cualquier operación anterior con un fallo de validación del dominio422{ "validationErrors": { "<field>": ["<message>"] } }
Cualquier operación anterior con un conflicto de estado, unicidad, conexión/OCPP, facturación, Tagless, conector o disponibilidad409{ "error": "<message>", "code": "CHARGER_CONFLICT" }
GET /chargers/:chargerId/sessions, intervalo de tiempo predeterminado o explícito no válido422{ "validationErrors": { "from": ["from must be before or equal to to"] } } o { "validationErrors": { "from": ["Session range cannot exceed 90 days"] } }

Las operaciones de lectura simples solo devuelven las respuestas compartidas 401/403/404/429/500/503, además de 422 para la validación de consultas y rutas. La eliminación de un cargador puede devolver la respuesta compartida 500 PlainError si falla sin un error más específico.

Errores de informes

EndpointsEstadoCuerpo exacto
Intervalo de datos/exportación en el que from >= to422{ "validationErrors": { "range": ["from must be earlier than to"] } }
Intervalo de datos/exportación superior a 90 días422{ "validationErrors": { "range": ["Report ranges cannot exceed 90 days"] } }
Cursor opaco no válido de datos/mediciones422{ "validationErrors": { "cursor": ["<message>"] } }
GET /reports/export, el resultado supera 2.000 filas422{ "error": "<message>", "code": "REPORT_EXPORT_ROW_LIMIT", "limit": 2000 }
POST /reports/send, sin programación guardada409{ "error": "A workspace report schedule must be saved before sending", "code": "REPORT_SCHEDULE_REQUIRED" }
Lo mismo, rechazo o fallo del servicio de correo502{ "error": "Report delivery failed", "code": "REPORT_DELIVERY_FAILED" }
No existe el recurso propio de programación/mediciones404cuerpo compartido RESOURCE_NOT_FOUND

La exportación correcta es binaria; todos los errores de exportación siguen siendo JSON.

Errores de tarifas

EndpointsEstadoCuerpo exacto
Validación de dominio para creación/actualización/componentes/precio de mercado/asignación422{ "validationErrors": { "<field>": ["<message>"] } }
Conflicto de eliminación de tarifa o de estado, dependencia o unicidad de asignación409{ "error": "<message>", "code": "TARIFF_CONFLICT" }
Tarifa, zona de oferta, cargador, conector, asignación de tarifa u otro recurso anidado fuera de la propiedad del espacio de trabajo404cuerpo compartido RESOURCE_NOT_FOUND

Errores de perfiles de carga

EndpointsEstadoCuerpo exacto
Validación de dominio para creación/actualización/programación/asignación422{ "validationErrors": { "<field>": ["<message>"] } }
Un uso protegido hace referencia al perfil409{ "error": "<message>", "code": "CHARGING_PROFILE_IN_USE" }
Conflicto de sincronización OCPP, asignación, concurrencia u otro conflicto de perfil409{ "error": "<message>", "code": "CHARGING_PROFILE_CONFLICT" }
Perfil, cargador, conector, asignación u otro recurso anidado fuera de la propiedad del espacio de trabajo404cuerpo compartido RESOURCE_NOT_FOUND

Errores del dominio de usuarios

Los errores de validación de usuarios que identifican un campo utilizan ValidationError más code; los demás errores de usuarios utilizan CodedError. Todos los casos de recursos no encontrados utilizan la respuesta compartida RESOURCE_NOT_FOUND, que no revela la existencia del recurso.

EstadoCódigo(s)Cuerpo
400INVALID_USER_CURSOR{ "validationErrors": { "cursor": ["The user-list cursor is invalid for the selected status"] }, "code": "INVALID_USER_CURSOR" }
409USER_ALREADY_EXISTS, CUSTOMER_CONTRACT_MISSING, INVITATION_EMAIL_IN_USE, RFID_ALREADY_EXISTS, ACCESS_ALREADY_EXISTS, ACCESS_ALL_ALREADY_EXISTS, LIMIT_ALREADY_EXISTS, LOCAL_USER_ALREADY_EXISTS, PROTECTED_WORKSPACE_USER, TAGLESS_USER_PROTECTED, USER_RELATED_DATA{ "error": "<message>", "code": "<listed code>" }
422INVALID_EMAIL, INVALID_RFID, INVALID_LIMIT_TYPE, INVALID_LIMIT_VALUE{ "validationErrors": { "<field>": ["<message>"] }, "code": "<listed code>" }
422NO_CHARGERS_AVAILABLE{ "error": "No chargers are available", "code": "NO_CHARGERS_AVAILABLE" }
429INVITATION_RESEND_THROTTLED{ "error": "Invitation resend is temporarily unavailable", "code": "INVITATION_RESEND_THROTTLED" }; incluye Retry-After
503USER_CURSOR_UNAVAILABLE{ "error": "User pagination is temporarily unavailable", "code": "USER_CURSOR_UNAVAILABLE" }
404RESOURCE_NOT_FOUND{ "error": "Workspace resource not found", "code": "RESOURCE_NOT_FOUND" }

POST /users/invitations también puede devolver la respuesta compartida 403 INSUFFICIENT_SCOPE tras analizar el cuerpo si falta users:access, o si se proporcionó un RFID y falta users:rfid. Los endpoints de usuarios locales enumeran todos los ámbitos obligatorios en la Referencia de endpoints.

Los códigos de error de usuarios se aplican así:

Familia de endpointsCódigos del dominio de usuarios distintos de 404, además de las respuestas compartidas
GET /usersINVALID_USER_CURSOR (400), USER_CURSOR_UNAVAILABLE (503)
POST /usersUSER_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409)
PATCH /users/:userIdTAGLESS_USER_PROTECTED (409)
DELETE /users/:userIdTAGLESS_USER_PROTECTED, PROTECTED_WORKSPACE_USER, USER_RELATED_DATA (409)
Lecturas de detalles del usuario, vehículos, RFID, accesos y límitesningún código de dominio distinto de 404
Creación de RFIDCUSTOMER_CONTRACT_MISSING, RFID_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409); INVALID_RFID (422)
Actualización/eliminación de RFIDTAGLESS_USER_PROTECTED (409)
Sustitución del accesoTAGLESS_USER_PROTECTED (409); NO_CHARGERS_AVAILABLE (422)
Revocación del accesoTAGLESS_USER_PROTECTED (409)
Creación/actualización de límiteTAGLESS_USER_PROTECTED, LIMIT_ALREADY_EXISTS (409); INVALID_LIMIT_TYPE, INVALID_LIMIT_VALUE (422)
Eliminación de límiteTAGLESS_USER_PROTECTED (409)
Creación de invitación al espacio de trabajoCUSTOMER_CONTRACT_MISSING, INVITATION_EMAIL_IN_USE, RFID_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409); INVALID_EMAIL/INVALID_RFID (422); INVITATION_RESEND_THROTTLED (429) cuando se aplica un tiempo de espera de entrega
Reenvío de invitación al espacio de trabajoINVALID_EMAIL (422), INVITATION_RESEND_THROTTLED (429)
Cancelación de invitación al espacio de trabajoINVALID_EMAIL (422)
Creación de usuario local del cargador para un cliente existenteLOCAL_USER_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409)
Invitación de usuario local del cargadorLOCAL_USER_ALREADY_EXISTS, INVITATION_EMAIL_IN_USE, TAGLESS_USER_PROTECTED (409); INVALID_EMAIL (422); INVITATION_RESEND_THROTTLED (429) cuando se aplica un tiempo de espera de entrega
Cancelación de invitación de usuario localINVALID_EMAIL (422)
Actualización/eliminación de usuario localTAGLESS_USER_PROTECTED (409)

Todos los resultados de propiedad y recurso no encontrado de esas familias, incluido un correo no registrado en POST /users, utilizan el cuerpo compartido 404 RESOURCE_NOT_FOUND.

Respuestas sin cuerpo y de repetición

Una respuesta 204 correcta no tiene cuerpo. Esto se aplica a todas las eliminaciones documentadas que indican 204 empty. Una repetición idempotente completada establece Idempotency-Replayed: true y utiliza el estado y el cuerpo guardados; para 204, la respuesta HTTP sigue sin cuerpo. La API nunca devuelve un objeto JSON de éxito para una operación 204 documentada.