← Dev Hub
Ayuda Venezuela

Venezuela Dev Hub · Estándares

Lineamientos de API

Propuesta de convenciones para equipos que construyen APIs en el ecosistema de respuesta. No son obligatorias. Si las seguís, cualquier app del ecosistema puede consumir tu data sin adaptadores.

1. Convenciones de endpoints

Base URL

Todas las rutas de API siguen el patrón: /api/v1/{recurso}

El prefijo /api/v1/ cumple dos funciones: separa las rutas de datos de las rutas HTML, y permite introducir cambios breaking en /api/v2/ sin romper las apps que ya usan v1.

GET  /api/v1/hospitales
GET  /api/v1/centros-de-acopio
GET  /api/v1/edificios-danados
GET  /api/v1/personas-desaparecidas

GET  /api/v1/hospitales?ciudad=Caracas&estado=Miranda
GET  /api/v1/centros-de-acopio?acepta=Agua
GET  /api/v1/edificios-danados?condicion=destruido

POST /api/v1/hospitales
POST /api/v1/centros-de-acopio

PATCH /api/v1/hospitales/{id}

Nomenclatura

Los recursos van en plural y kebab-case:

El kebab-case es el estándar en URLs. El plural deja claro que el endpoint retorna una colección.

Filtros como query params

Los filtros van en query params, nunca en el path. Se pueden combinar múltiples filtros en un mismo request:

GET /api/v1/hospitales?ciudad=Caracas&estado=Miranda&activo=true

Los query params son más flexibles que los paths. Evitás la explosión combinatoria de rutas y la API es más fácil de documentar.

2. DTOs por recurso

Cada recurso tiene un contrato de datos propuesto. El objetivo es que si dos apps distintas tienen información de hospitales, cualquier consumidor pueda leer ambas sin adaptadores. Los campos obligatorios están marcados — el resto puede omitirse si no tenés el dato.

Campos comunes a todos los recursos

id (UUID v4), verificado (boolean — aprobado por un moderador), fuente (URL o handle de quien reportó el dato). Usar ISO 8601 para todos los timestamps: "2026-06-28T14:30:00Z".

Hospital

{
  "id": "uuid",
  "nombre": "string",
  "direccion": "string",
  "ciudad": "string",
  "estado": "string (estado venezolano)",
  "lat": "number | null",
  "lng": "number | null",
  "activo": "boolean",
  "insumos": [
    {
      "nombre": "string",
      "prioridad": "alta | media | baja",
      "cantidad_estimada": "number | null"
    }
  ],
  "areas_afectadas": ["Emergencias", "UCI", "Pediatría"],
  "fuente": "string (url o handle)",
  "verificado": "boolean",
  "ultima_actualizacion": "ISO 8601"
}

Centro de acopio

{
  "id": "uuid",
  "nombre": "string",
  "direccion": "string",
  "ciudad": "string",
  "estado": "string",
  "lat": "number | null",
  "lng": "number | null",
  "horario": "string | null",
  "activo": "boolean",
  "acepta": ["Ropa", "Agua", "Medicamentos", "Alimentos"],
  "contacto": "string (teléfono o Telegram)",
  "fuente": "string",
  "verificado": "boolean",
  "ultima_actualizacion": "ISO 8601"
}

Edificio dañado

{
  "id": "uuid",
  "direccion": "string",
  "ciudad": "string",
  "estado": "string",
  "lat": "number | null",
  "lng": "number | null",
  "pisos": "number | null",
  "apartamentos": "number | null",
  "familias_estimadas": "number | null",
  "condicion": "inhabitable | dañado | destruido",
  "fuente": "string",
  "verificado": "boolean",
  "reportado_en": "ISO 8601"
}

Persona desaparecida

{
  "id": "uuid",
  "nombre": "string",
  "edad": "number | null",
  "ultima_ubicacion_conocida": "string",
  "ciudad": "string",
  "estado": "string",
  "contacto_familiar": "string",
  "foto_url": "string | null",
  "encontrado": "boolean",
  "reportado_en": "ISO 8601"
}

Consideraciones de privacidad

foto_url es opcional y nunca requerido. Considerar GDPR/LOPD si tu app almacena fotos. El campo encontrado debe poder actualizarse con un PATCH rápido.

3. Formato de respuesta

Todas las respuestas exitosas tienen el mismo envelope. Esto facilita que el código consumidor sea genérico: siempre leer response.data, siempre leer response.meta.total.

{
  "data": [...],
  "meta": {
    "total": 42,
    "page": 1,
    "per_page": 50
  },
  "error": null
}

4. Códigos de error

Todos los errores retornan JSON con el mismo formato. Nunca retornar HTML en un error de API.

{
  "error": {
    "code": "MISSING_FIELD",
    "message": "El campo 'ciudad' es requerido."
  }
}
HTTP error.code Cuándo usarlo
400 MISSING_FIELD Campo requerido faltante. Indicar el nombre del campo en message.
400 INVALID_VALUE Valor que no corresponde al tipo o enum esperado.
404 NOT_FOUND Recurso con ese ID no existe.
429 RATE_LIMIT Demasiadas requests. Incluir Retry-After header con segundos de espera.
500 INTERNAL_ERROR Error interno. No exponer detalles del stack trace.

5. CORS y autenticación

APIs de lectura (GET)

APIs de escritura (POST/PATCH)

Regla de emergencia

Nunca requerir API key para leer datos de emergencia. Una persona que necesita saber dónde hay un centro de acopio no puede esperar el proceso de obtener una clave de API.

¿Tenés sugerencias?

Estos lineamientos son una propuesta abierta. Si encontrás un caso que no está cubierto o querés proponer un cambio, abrí la conversación en el grupo de desarrolladores.

Sugerir cambios en Telegram →