API de Huella Vital

Acceso público de solo lectura al directorio veterinario más completo de Venezuela: clínicas, ciudades, servicios y precios en JSON.

URL base

https://huellavital.com/api/v1

Todas las respuestas son JSON UTF-8. CORS abierto (Access-Control-Allow-Origin: *) para peticiones GET desde cualquier origen.

Sin autenticación

La API de lectura es pública: sin API keys, sin registro, sin fricción. Los endpoints de escritura/administración no forman parte de esta API y permanecen protegidos.

Límite de peticiones

60 peticiones/minuto por IP (best-effort). Si lo superas recibirás 429 con cabecera Retry-After. Cada respuesta incluye X-RateLimit-*.

Limitación honesta del rate limit

El límite se implementa con un token bucket en memoria por instancia del servidor; las instancias serverless no comparten estado, así que en despliegues multi-instancia el límite efectivo es por instancia, no global. Es el mejor esfuerzo posible sin infraestructura compartida (aún no existe Redis/KV/BD). Cuando llegue la capa Supabase se migrará a un almacén compartido sin cambiar el contrato.

Caché

Las respuestas exitosas llevan Cache-Control: public, s-maxage=300, stale-while-revalidate=3600: la CDN las sirve durante 5 minutos y admite contenido envejecido hasta 1 hora mientras revalida. Los errores nunca se cachean.

Errores

Todos los errores usan el mismo sobre con códigos de estado HTTP correctos (400 parámetro inválido, 404 no encontrado, 405 método no permitido, 429 límite excedido, 500 error interno):

json
{
  "error": {
    "code": "not_found",
    "message": "No clinic with slug \"esta-clinica-no-existe\". Use GET /api/v1/clinics to browse valid slugs."
  }
}

Códigos de error: invalid_parameter, unknown_city, unknown_service, not_found, method_not_allowed, rate_limited, internal_error.

Referencia

Endpoints

Cada ejemplo se puede copiar y pegar tal cual; las respuestas mostradas son respuestas reales capturadas de esta API.

GET/api/v1

Índice de descubrimiento: versión, lista de endpoints, enlaces a esta documentación y al OpenAPI, y conteos en vivo del directorio.

bash
curl -s https://huellavital.com/api/v1 | json_pp
js
const res = await fetch("https://huellavital.com/api/v1");
const api = await res.json();
console.log(api.counts); // { clinics, cities, services }
json
{
  "name": "Huella Vital Directory API",
  "version": "1.0.0",
  "description": "Public read API for the Huella Vital veterinary directory of Venezuela: clinics, cities, services and price aggregates.",
  "documentation": "https://huellavital.com/api-docs",
  "openapi": "https://huellavital.com/api/v1/openapi.json",
  "endpoints": [
    {
      "path": "/api/v1/clinics",
      "methods": [
        "GET"
      ],
      "description": "List clinics. Paginated (page, limit<=100) with filters: city, service, q (name substring), has_phone."
    },
    {
      "path": "/api/v1/clinics/{slug}",
      "methods": [
        "GET"
      ],
      "description": "Full clinic object: hours, description, prices map, related URLs."
    },
    {
      "path": "/api/v1/cities",
      "methods": [
        "GET"
      ],
      "description": "Cities with clinic counts and slugs."
    },
    {
      "path": "/api/v1/cities/{ciudad}",
      "methods": [
        "GET"
      ],
      "description": "City detail plus its barrios with clinic counts."
    },
    {
      "path": "/api/v1/services",
      "methods": [
        "GET"
      ],
      "description": "Service catalogue with clinic counts."
    },
    {
      "path": "/api/v1/prices",
      "methods": [
        "GET"
      ],
      "description": "Price aggregates (service averages + verified clinic-level reports). Clinic-level prices are still sparsely populated — see `coverage`."
    },
    {
      "path": "/api/v1/openapi.json",
      "methods": [
        "GET"
      ],
      "description": "OpenAPI 3.1 specification of this API."
    }
  ],
  "counts": {
    "clinics": 318,
    "cities": 12,
    "services": 8
  },
  "rateLimit": {
    "policy": "best-effort per client IP",
    "limit": 60,
    "windowSeconds": 60,
    "note": "In-memory per server instance; serverless instances do not share state."
  }
}
GET/api/v1/clinics

Lista paginada de clínicas. Orden estable: mejor valoradas primero (rating descendente, sin rating al final), luego por número de opiniones y finalmente por slug.

ParámetroTipoDescripción
pageinteger ≥ 1Página (1-based). Por defecto 1.
limitinteger 1–100Resultados por página. Por defecto 20.
citystring (slug)Filtra por ciudad. Slugs válidos en /api/v1/cities. Slug desconocido → 400.
servicestring (slug)Filtra por servicio. Slugs válidos en /api/v1/services. Slug desconocido → 400.
qstring ≤ 100Subcadena sobre el nombre, insensible a mayúsculas y tildes.
has_phonetrue | falseSolo clínicas con (o sin) teléfono.
bash
curl -s "https://huellavital.com/api/v1/clinics?city=caracas&service=urgencias-24h&has_phone=true&limit=2" | json_pp
js
const params = new URLSearchParams({
  city: "caracas",
  service: "urgencias-24h",
  has_phone: "true",
  limit: "2",
});
const res = await fetch(`https://huellavital.com/api/v1/clinics?${params}`);
const { data, pagination } = await res.json();
json
{
  "data": [
    {
      "slug": "emergencias-veterinarias-santa-eduvigis-caracas",
      "name": "Emergencias Veterinarias Santa Eduvigis",
      "city": {
        "name": "Caracas",
        "slug": "caracas"
      },
      "neighborhood": null,
      "address": "Segunda Avenida de Santa Eduvigis, Urb. Santa Eduvigis, Edif. Imperial PB, Caracas 1071, Miranda, Venezuela",
      "phone": "+58 424-1372694",
      "services": [
        "Consulta general"
      ],
      "rating": 5,
      "reviews": 2,
      "coordinates": null,
      "isEmergency": true,
      "url": "https://huellavital.com/clinica/emergencias-veterinarias-santa-eduvigis-caracas"
    },
    {
      "slug": "centro-veterinario-la-trinidad-emergencias-veterin-caracas",
      "name": "Centro Veterinario La Trinidad Emergencias veterinarias 24 horas",
      "city": {
        "name": "Caracas",
        "slug": "caracas"
      },
      "neighborhood": null,
      "address": "Av. González Rincones, Caracas 1080, Miranda, Venezuela",
      "phone": "0414-2921506",
      "services": [
        "Consulta general",
        "Vacunación",
        "Laboratorio"
      ],
      "rating": 4.8,
      "reviews": 200,
      "coordinates": null,
      "isEmergency": true,
      "url": "https://huellavital.com/clinica/centro-veterinario-la-trinidad-emergencias-veterin-caracas"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 2,
    "total": 18,
    "totalPages": 9,
    "hasNextPage": true,
    "hasPrevPage": false
  },
  "filters": {
    "city": "caracas",
    "service": "urgencias-24h",
    "q": null,
    "has_phone": true
  }
}
GET/api/v1/clinics/{slug}

Ficha completa de una clínica: horarios, descripción (cuando existe), el mapa de precios prices (hoy vacío — el esquema ya está listo) y URLs relacionadas (ficha web, ciudad, barrio).

bash
curl -s https://huellavital.com/api/v1/clinics/dr24hveterinario-barquisimeto | json_pp
json
{
  "data": {
    "slug": "dr24hveterinario-barquisimeto",
    "name": "Dr24HVeterinario",
    "city": {
      "name": "Barquisimeto",
      "slug": "barquisimeto"
    },
    "neighborhood": null,
    "address": "Etapa 3 C. 2A, Cabudare 3023, Lara, Venezuela",
    "phone": "0424-5549642",
    "services": [
      "Consulta general",
      "Urgencias 24h"
    ],
    "rating": 5,
    "reviews": 52,
    "coordinates": null,
    "isEmergency": true,
    "url": "https://huellavital.com/clinica/dr24hveterinario-barquisimeto",
    "id": "ChIJmTKwxB9fh44Rr4AUCe_aRdM",
    "email": null,
    "website": null,
    "hours": [
      "Abierto 24 horas, todos los días"
    ],
    "description": "Dr24HVeterinario - Veterinaria excelente en Venezuela. excelente reputación con clientes satisfechos. Atención de calidad para mascotas.",
    "prices": {},
    "images": [],
    "lastUpdated": "2026-03-01T17:12:05.404342",
    "source": "google_places_v1",
    "urls": {
      "self": "https://huellavital.com/api/v1/clinics/dr24hveterinario-barquisimeto",
      "web": "https://huellavital.com/clinica/dr24hveterinario-barquisimeto",
      "city": "https://huellavital.com/veterinarias/barquisimeto",
      "neighborhood": null
    }
  }
}
GET/api/v1/cities

Ciudades del directorio con su slug y número de clínicas, ordenadas de mayor a menor cobertura.

bash
curl -s https://huellavital.com/api/v1/cities | json_pp
js
const res = await fetch("https://huellavital.com/api/v1/cities");
const { data: cities } = await res.json();
json
{
  "data": [
    {
      "name": "Caracas",
      "slug": "caracas",
      "clinicCount": 84,
      "url": "https://huellavital.com/veterinarias/caracas"
    },
    {
      "name": "Valencia",
      "slug": "valencia",
      "clinicCount": 47,
      "url": "https://huellavital.com/veterinarias/valencia"
    },
    {
      "name": "Maracaibo",
      "slug": "maracaibo",
      "clinicCount": 26,
      "url": "https://huellavital.com/veterinarias/maracaibo"
    },
    {
      "name": "Barquisimeto",
      "slug": "barquisimeto",
      "clinicCount": 24,
      "url": "https://huellavital.com/veterinarias/barquisimeto"
    },
    {
      "name": "Maracay",
      "slug": "maracay",
      "clinicCount": 23,
      "url": "https://huellavital.com/veterinarias/maracay"
    },
    {
      "name": "Maturín",
      "slug": "maturín",
      "clinicCount": 20,
      "url": "https://huellavital.com/veterinarias/maturín"
    },
    {
      "name": "Ciudad Guayana",
      "slug": "ciudad-guayana",
      "clinicCount": 20,
      "url": "https://huellavital.com/veterinarias/ciudad-guayana"
    },
    {
      "name": "San Cristóbal",
      "slug": "san-cristóbal",
      "clinicCount": 20,
      "url": "https://huellavital.com/veterinarias/san-cristóbal"
    },
    {
      "name": "Barinas",
      "slug": "barinas",
      "clinicCount": 19,
      "url": "https://huellavital.com/veterinarias/barinas"
    },
    {
      "name": "Punto Fijo",
      "slug": "punto-fijo",
      "clinicCount": 16,
      "url": "https://huellavital.com/veterinarias/punto-fijo"
    },
    {
      "name": "Barcelona",
      "slug": "barcelona",
      "clinicCount": 10,
      "url": "https://huellavital.com/veterinarias/barcelona"
    },
    {
      "name": "Los Teques",
      "slug": "los-teques",
      "clinicCount": 9,
      "url": "https://huellavital.com/veterinarias/los-teques"
    }
  ]
}
GET/api/v1/cities/{ciudad}

Detalle de una ciudad y sus barrios con conteo de clínicas.

bash
curl -s https://huellavital.com/api/v1/cities/caracas | json_pp
json
{
  "data": {
    "name": "Caracas",
    "slug": "caracas",
    "clinicCount": 84,
    "url": "https://huellavital.com/veterinarias/caracas",
    "barrios": [
      {
        "name": "Baruta",
        "slug": "baruta",
        "clinicCount": 5,
        "url": "https://huellavital.com/veterinarias/caracas/baruta"
      },
      {
        "name": "El Hatillo",
        "slug": "el-hatillo",
        "clinicCount": 3,
        "url": "https://huellavital.com/veterinarias/caracas/el-hatillo"
      },
      {
        "name": "Chacao",
        "slug": "chacao",
        "clinicCount": 3,
        "url": "https://huellavital.com/veterinarias/caracas/chacao"
      },
      {
        "name": "El Recreo",
        "slug": "el-recreo",
        "clinicCount": 1,
        "url": "https://huellavital.com/veterinarias/caracas/el-recreo"
      }
    ]
  }
}
GET/api/v1/services

Catálogo público de 8 servicios con el número de clínicas que ofrecen cada uno. Los slugs de esta lista son los valores válidos del filtro service de /api/v1/clinics.

bash
curl -s https://huellavital.com/api/v1/services | json_pp
json
{
  "data": [
    {
      "slug": "vacunacion",
      "name": "Vacunación",
      "clinicCount": 84,
      "url": "https://huellavital.com/servicios/vacunacion"
    },
    {
      "slug": "esterilizacion",
      "name": "Esterilización",
      "clinicCount": 0,
      "url": "https://huellavital.com/servicios/esterilizacion"
    },
    {
      "slug": "urgencias-24h",
      "name": "Urgencias 24h",
      "clinicCount": 24,
      "url": "https://huellavital.com/servicios/urgencias-24h"
    },
    {
      "slug": "cirugia",
      "name": "Cirugía",
      "clinicCount": 13,
      "url": "https://huellavital.com/servicios/cirugia"
    },
    {
      "slug": "laboratorio",
      "name": "Laboratorio",
      "clinicCount": 86,
      "url": "https://huellavital.com/servicios/laboratorio"
    },
    {
      "slug": "radiografia",
      "name": "Radiografía",
      "clinicCount": 0,
      "url": "https://huellavital.com/servicios/radiografia"
    },
    {
      "slug": "peluqueria",
      "name": "Peluquería",
      "clinicCount": 0,
      "url": "https://huellavital.com/servicios/peluqueria"
    },
    {
      "slug": "hospitalizacion",
      "name": "Hospitalización",
      "clinicCount": 13,
      "url": "https://huellavital.com/servicios/hospitalizacion"
    }
  ]
}
GET/api/v1/prices

Agregados de precios en USD: promedios por servicio, estadísticas y los reportes verificados por clínica que existen hoy. Los precios por clínica aún están mayormente vacíos — el esquema ya los admite (prices en cada clínica) y la recolección está en marcha. Revisa coverage antes de construir sobre estos datos.

bash
curl -s https://huellavital.com/api/v1/prices | json_pp
json
{
  "data": {
    "currency": "USD",
    "generatedAt": "2026-03-04T13:49:54.403708",
    "stats": {
      "total_clinics": 5,
      "total_price_entries": 10,
      "sources": {
        "manual": 9,
        "test": 1
      },
      "services_offered": 5,
      "last_updated": "2026-03-04T13:49:54.403724"
    },
    "serviceAverages": {
      "cirugia_menor": {
        "average": 150,
        "range": [
          150,
          150
        ]
      },
      "consulta_general": {
        "average": 26,
        "range": [
          22,
          30
        ]
      },
      "esterilizacion_gata": {
        "average": 80,
        "range": [
          80,
          80
        ]
      },
      "urgencias": {
        "average": 50,
        "range": [
          50,
          50
        ]
      },
      "vacuna_rabia": {
        "average": 13.5,
        "range": [
          12,
          15
        ]
      }
    },
    "clinicPrices": {
      "Clínica Veterinaria La Trinidad": {
        "consulta_general": {
          "price": 25,
          "currency": "USD",
          "date": "2026-02-26",
          "source": "manual",
          "notes": null
        },
        "vacuna_rabia": {
          "price": 15,
          "currency": "USD",
          "date": "2026-02-26",
          "source": "manual",
          "notes": null
        },
        "esterilizacion_gata": {
          "price": 80,
          "currency": "USD",
          "date": "2026-02-26",
          "source": "manual",
          "notes": null
        }
      },
      "Perro Amor 24H": {
        "consulta_general": {
          "price": 30,
          "currency": "USD",
          "date": "2026-02-26",
          "source": "manual",
          "notes": null
        },
        "urgencias": {
          "price": 50,
          "currency": "USD",
          "date": "2026-02-26",
          "source": "manual",
          "notes": null
        }
      },
      "Hospital Veterinario El Paraíso": {
        "consulta_general": {
          "price": 28,
          "currency": "USD",
          "date": "2026-02-26",
          "source": "manual",
          "notes": null
        },
        "cirugia_menor": {
          "price": 150,
          "currency": "USD",
          "date": "2026-02-26",
          "source": "manual",
          "notes": null
        }
      },
      "Veterinaria Vuurman": {
        "consulta_general": {
          "price": 22,
          "currency": "USD",
          "date": "2026-02-26",
          "source": "manual",
          "notes": null
        },
        "vacuna_rabia": {
          "price": 12,
          "currency": "USD",
          "date": "2026-02-26",
          "source": "manual",
          "notes": null
        }
      }
    },
    "coverage": {
      "clinicsWithPrices": 4,
      "totalClinics": 318
    },
    "note": "Clinic-level prices are largely unpopulated today: the directory schema is price-ready (every clinic object carries a `prices` map) but collection is still ramping up. `clinicPrices` contains the verified reports gathered so far; `serviceAverages` aggregates them. Use `coverage` to gauge sparsity before building on price data."
  }
}

Nota de arquitectura

Hoy los datos se normalizan en tiempo de build desde el pipeline interno del sitio. Todos los handlers de /api/v1 leen exclusivamente a través del módulo src/data/api.ts: cuando aterrice la capa Supabase será un reemplazo de un solo archivo, sin tocar rutas ni este contrato. ¿Comentarios o casos de uso? Escríbenos.