# Respuestas y errores

> El sobre de toda respuesta, el array errors que llega siempre, los códigos HTTP y qué hacer con cada uno, los mensajes de validación y de negocio, el idioma de los mensajes y los elementos eliminados.

Todas las respuestas de la API llegan en el mismo sobre. Así, un único tratamiento sirve para todas las llamadas.

## Éxito

```json
{
  "success": true,
  "message": "Login successful.",
  "data": { },
  "pagination": { "page": 1, "limit": 20, "total": 137, "totalPages": 7 }
}
```

`pagination` solo aparece en los listados. Consulta [Paginación](/api/paginacao).

## Error

```json
{
  "success": false,
  "message": "Valid email is required",
  "errors": [{ "param": "email", "message": "Valid email is required" }]
}
```

- El array `errors` llega **siempre**, aunque solo haya un error.
- `param` indica qué campo causó el error, cuando lo hay.
- `message` es el mensaje que hay que mostrar.

Así, la validación y las reglas de negocio se tratan por el mismo camino: muestra `errors[].message` junto al campo `param`; sin `param`, muéstralo arriba.

## Los dos tipos de error

| Tipo | Ejemplo | Cómo reconocerlo |
|---|---|---|
| **Validación** | Un campo que falta o con un formato incorrecto | `400`, `param` = el campo, mensaje corto (*"Title is required"*) |
| **Regla de negocio** | Una acción que el estado actual no permite | `400`, `403`, `404` o `409`, con un mensaje que lo explica (*"Saldo insuficiente…"*) |

## Códigos

| Código | Significa | Qué hacer |
|---|---|---|
| `200` / `201` | Ha ido bien (`201` cuando crea) | — |
| `204` | Ha ido bien, sin cuerpo (eliminaciones) | — |
| `400` | La validación ha fallado, o falta el `X-CommunityId` (`errors[0].param = "X-CommunityId"`) | Lee `errors` y corrige |
| `401` | Token ausente, no válido o caducado | Vuelve a iniciar sesión |
| `402` | El pago se ha rechazado | Muestra el mensaje al comprador |
| `403` | Sin permiso: rol insuficiente, o el espacio restringe quién crea | Revisa el rol y el `X-CommunityId` |
| `404` | No existe, se ha eliminado, es de otra comunidad, o la ruta es una de las antiguas con `/communities/{communityId}/` | Revisa el id, la comunidad y la [ruta](/api/x-community-id#las-rutas-que-cambiaron) |
| `409` | Conflicto con el estado actual | Lee el mensaje |
| `429` | Demasiados intentos (p. ej.: 10 códigos de cupón no válidos en 15 minutos) | Espera unos minutos |
| `500` | Error interno | Inténtalo de nuevo; si persiste, escribe al soporte |

## Ejemplos reales

| Situación | Respuesta |
|---|---|
| Listar productos sin la cabecera `X-CommunityId` | `400` · *Indica la comunidad en el encabezado X-CommunityId.*, con `param: "X-CommunityId"` |
| Crear un espacio en una sección que no existe | `400` · *Seção não encontrada ou não pertence a esta comunidade.* ("Sección no encontrada o no pertenece a esta comunidad") |
| Crear un módulo de curso en un curso que no existe | `404` · *Course not found* |
| Un miembro publicando en un espacio "Equipo" | `403` · *Solo el equipo (administrador, propietario, moderador) puede realizar esta acción* |
| Un administrador modificando a un propietario | `403` · *Solo un owner o un SuperAdmin puede eliminar, degradar o modificar a un owner.* |
| Quitar de un plan un adicional con suscriptores | `409` · *No se puede quitar este complemento del plan…* |

Más ejemplos, en el orden en que aparecen al montar algo, en [Orden de creación](/api/ordem-de-criacao).

## Idioma de los mensajes

Los mensajes llegan en el idioma de la cabecera `Accept-Language` (`pt-BR`, `en-US`, `es-ES`, `it-IT`, `de-DE` y las demás variantes). Algunas validaciones de formato todavía responden en inglés, y algunos mensajes, en portugués.

## Elemento de otra comunidad

Un elemento que pertenece a otra comunidad responde **404**, igual que un id que no existe. La API no revela que el elemento existe en otro lugar: para quien llama, no existe en la comunidad del `X-CommunityId`.

| Cuándo | Respuesta |
|---|---|
| La ruta nombra un espacio de otra comunidad (`?spaceId=`, el espacio de un curso o de una convocatoria) | `404` · `space.notFound` |
| La ruta nombra un elemento de otra comunidad (leer un contenido, sus comentarios, los participantes de un evento) | `404` · `common.notFound` |
| Editar, eliminar, comentar, reaccionar o fijar contenido, un evento o un estado de otra comunidad | `404` · el mensaje del módulo (`content.notFound`, `event.notFound`, `status.notFound`, `course.notFound`) |

Ser propietario, administrador o moderador en una comunidad no da acceso a nada de otra, ni siquiera enviando la cabecera de la tuya. Si el elemento es de la comunidad y aun así responde 404, comprueba que el `X-CommunityId` sea el de la comunidad correcta.

## Elementos eliminados

La API no borra de verdad: los elementos eliminados se marcan como tales y dejan de aparecer. Por eso un id eliminado responde **404**, como si nunca hubiera existido.

## Con el SDK

El SDK lanza `MemberfyError` con `.status`, `.body` (el sobre entero) y `.errors`. Consulta [SDK de JavaScript](/api/sdk-js).

## Relacionados

- [Autenticación](/api/autenticacao)
- [X-CommunityId](/api/x-community-id)
- [Orden de creación](/api/ordem-de-criacao)
