Referencia de la API
Acceso de solo lectura a los anuncios y sus fotos, más el aviso que crea el botón «¡Yo lo tengo!». Sigue la convención JSON:API y necesita una clave que entregamos nosotros.
Lo básico
- URL base
https://encuentratumascota.co/api/v1- Tipo de medio
application/vnd.api+json
Toda respuesta sale con ese tipo de medio. Si envías cuerpo, la cabecera
Content-Type debe ser exactamente esa cadena:
un ; charset=utf-8 añadido se rechaza con 415,
como manda la especificación.
Autenticación
Cada consumidor recibe su propia clave. Mándala en cada petición; sin ella la respuesta es
401. Si tu cliente reserva la cabecera
Authorization para otra cosa, usa
X-Api-Key con el mismo valor.
Authorization: Bearer TU_CLAVE
La clave identifica a tu aplicación y es por lo que contamos los límites de uso. Trátala como una contraseña: no la publiques en código de cliente ni en un repositorio. Si se te filtra, avísanos y la revocamos.
Listar anuncios
/api/v1/pet-ads
Devuelve solo los anuncios activos, del más reciente al más antiguo, salvo que pidas otra cosa.
Filtros
| Parámetro | Valores | Qué hace |
|---|---|---|
filter[adType] |
searching (Se busca), found (Se busca familia) | Cuál de las dos pestañas: mascota perdida o encontrada. |
filter[petType] |
dog (Perro), cat (Gato), other (Otra) | Especie de la mascota. |
filter[status] |
active (Activo), resolved (Resuelto) | Por defecto solo devuelve los activos. Pide «resolved» para los ya resueltos. |
filter[city] |
texto libre | Coincidencia parcial, sin distinguir mayúsculas ni el resto del nombre. |
filter[name] |
texto libre | Nombre de la mascota, también por coincidencia parcial. |
Orden, página y relaciones
-
sort— -createdAt, createdAt, city, -city. Por defecto-createdAt. -
page[number]ypage[size]— 25 por página por defecto, máximo 100. Siguelinks.nexten vez de armar la URL a mano. -
include=photos— agrega las fotos completas bajoincluded. Sin esto igual recibes qué fotos tiene cada anuncio enrelationships, pero sin sus URLs. -
fields[pet-ads]yfields[pet-ad-photos]— lista separada por comas para recortar la respuesta a los campos que de verdad usas.
Un parámetro que no exista, o con un valor fuera de rango, responde 400. Nunca lo ignoramos en silencio: si pediste algo mal, te enteras.
curl -H 'Accept: application/vnd.api+json' \
-H "Authorization: Bearer $CLAVE" \
'https://encuentratumascota.co/api/v1/pet-ads?filter[adType]=searching&filter[city]=Medellin&include=photos&page[size]=10'
{
"data": [
{
"type": "pet-ads",
"id": "1d14daa9-6f6e-4d0a-9f8c-2b0f5a1c7e33",
"attributes": {
"adType": "searching",
"adTypeLabel": "Se busca",
"status": "active",
"petType": "cat",
"petTypeLabel": "Gato",
"title": "Ilona",
"name": "Ilona",
"breed": "Criolla",
"color": "Gris atigrado",
"city": "Pereira",
"zone": "Centro",
"location": "Centro, Pereira",
"phoneVisible": true,
"phone": "573001234567",
"phoneFormatted": "+57 300 123 4567",
"whatsappUrl": "https://wa.me/573001234567",
"acceptsReports": true,
"createdAt": "2026-08-16T13:33:05+00:00"
},
"relationships": {
"photos": {
"data": [
{ "type": "pet-ad-photos", "id": "196" }
]
}
},
"links": {
"self": "https://encuentratumascota.co/api/v1/pet-ads/1d14daa9-6f6e-4d0a-9f8c-2b0f5a1c7e33"
}
}
],
"included": [
{
"type": "pet-ad-photos",
"id": "196",
"attributes": {
"url": "https://.../anuncios/1d14daa9/foto.jpg",
"isPrimary": true,
"position": 0
}
}
],
"links": {
"self": "https://encuentratumascota.co/api/v1/pet-ads",
"next": "https://encuentratumascota.co/api/v1/pet-ads?page%5Bnumber%5D=2"
},
"meta": {
"page": {
"number": 1,
"size": 10,
"total": 102,
"lastPage": 11
}
}
}
El teléfono solo viaja cuando quien publicó eligió mostrarlo y el
anuncio sigue activo: al marcarlo como resuelto se retira, porque ya cumplió su propósito. Por eso
phoneVisible siempre está, y
phone puede no estar. Si está oculto, la forma de
llegar a esa persona es crear un aviso.
Ver un anuncio
/api/v1/pet-ads/{uuid}
Mismo objeto que en el listado, dentro de data en vez de
un arreglo. Acepta include y
fields. Devuelve el anuncio esté activo o resuelto;
un UUID que no existe da 404.
curl -H 'Accept: application/vnd.api+json' \
-H "Authorization: Bearer $CLAVE" \
'https://encuentratumascota.co/api/v1/pet-ads/1d14daa9-6f6e-4d0a-9f8c-2b0f5a1c7e33?include=photos'
Dejar un aviso
/api/v1/pet-ads/{uuid}/reports
La única escritura de la API: alguien vio la mascota y deja su celular para que la familia lo contacte. Guardamos el número y le mandamos el aviso por WhatsApp a quien publicó; el envío va por fuera de la petición, así que un 201 significa «recibido y encolado», no «ya entregado».
El celular son 10 dígitos empezando por 3, sin indicativo de país. Puedes mandarlo con espacios o con «+57» adelante, nosotros lo normalizamos.
curl -X POST \
-H 'Content-Type: application/vnd.api+json' \
-H "Authorization: Bearer $CLAVE" \
-d '{"data":{"type":"pet-ad-reports","attributes":{"phone":"3009876543"}}}' \
'https://encuentratumascota.co/api/v1/pet-ads/1d14daa9-6f6e-4d0a-9f8c-2b0f5a1c7e33/reports'
{
"data": {
"type": "pet-ad-reports",
"id": "3",
"attributes": {
"status": "pending",
"statusLabel": "Pendiente de envío",
"notifiedAt": null,
"createdAt": "2026-08-16T16:04:11+00:00"
},
"relationships": {
"petAd": {
"data": { "type": "pet-ads", "id": "1d14daa9-6f6e-4d0a-9f8c-2b0f5a1c7e33" }
}
}
}
}
No te devolvemos el celular que enviaste: es de quien lo dejó, y la API no sirve para leer los avisos de otros. Un anuncio ya resuelto responde 409, no 404: el anuncio existe, solo dejó de recibir avisos.
Errores
Todo error llega como una lista errors, con un objeto
por cada problema encontrado — así puedes resaltar todos los campos malos de una sola vez.
{
"errors": [
{
"status": "422",
"code": "validation_error",
"title": "Datos inválidos",
"detail": "El celular debe empezar por 3.",
"source": { "pointer": "/data/attributes/phone" }
}
]
}
| Estado | Código | Cuándo |
|---|---|---|
| 400 | invalid_query_parameter |
Un filtro, sort, include o fields que no existe, o con un valor fuera de rango. El error apunta al parámetro en «source.parameter». |
| 401 | unauthorized |
Falta la API key o no corresponde a ningún cliente. |
| 404 | not_found |
No hay ningún anuncio con ese UUID. |
| 406 | not_acceptable |
El «Accept» solo pide el tipo de medio con parámetros añadidos. |
| 409 | invalid_resource_type |
El «data.type» del cuerpo nombra otro recurso. |
| 409 | ad_not_accepting_reports |
El anuncio ya está resuelto y dejó de recibir avisos. |
| 415 | unsupported_media_type |
El cuerpo no viaja como «application/vnd.api+json», o lo hace con parámetros de tipo de medio. |
| 422 | validation_error |
El cuerpo tiene la forma correcta pero un valor no pasa validación. Apunta al miembro en «source.pointer». |
| 429 | too_many_requests |
Se agotó el límite por minuto. La respuesta trae la cabecera «Retry-After». |
Límites de uso
- 120 lecturas por minuto.
- 2 avisos por minuto, porque cada uno termina en un WhatsApp a una persona real.
Se cuentan por clave, no por dirección IP, así que otro consumidor no te gasta el cupo. Al pasarte
recibes 429 con la cabecera
Retry-After; espera esos segundos antes de reintentar.
¿Necesitas una clave o encontraste algo que no cuadra con esta página? Escríbenos y lo revisamos.