Convenciones
Esto se cumple en todos los endpoints, así que se describe una vez aquí en lugar de repetirse en cada uno.
Paginación
Las colecciones se paginan por cursor, no por desplazamiento. Un desplazamiento es inestable sobre un catálogo que cambia mientras lo recorres: inserta una ficha durante un barrido y la paginación por desplazamiento repite una en silencio; borra una y se salta otra en silencio. Un cursor apunta a una posición en un orden estable, así que no ocurre ninguna de las dos cosas.
# Primera página
GET /v1/api/properties?city=Berlin&limit=100
# Todas las páginas siguientes
GET /v1/api/properties?city=Berlin&limit=100&cursor=eyJpZCI6…Para cuando meta.has_more sea falso. No pares por una página corta, y no
calcules un número de páginas: no hay total, deliberadamente, porque contar un conjunto grande
y filtrado es caro y la respuesta está desfasada en cuanto se devuelve.
Todos los clientes tienen un iterador que hace esto por ti. Consulta paginación.
Trata un cursor como opaco. Codifica la posición de orden y el estado de los filtros, así que solo es válido contra la misma consulta, y decodificar uno para construirte el tuyo no está soportado.
Mantener acompasada una copia
No releas un mercado con un temporizador. Recórrelo una vez, guarda el updated_at más
nuevo que hayas visto y pide después solo lo que ha cambiado desde entonces:
GET /v1/api/properties?city=Berlin&updated_since=2026-08-11T04:00:00ZSolapa la ventana unos minutos en lugar de usar la marca de tiempo exacta de tu última pasada. Las fichas se escriben de forma concurrente, así que un límite estricto puede saltarse una confirmada un instante después de tu corte. Tratar dos veces la misma ficha es inofensivo si tu escritura es un upsert; saltarse una no lo es.
Los webhooks eliminan por completo la necesidad de este bucle.
Filtrar y ordenar
Los filtros se combinan con AND. Repetir un parámetro forma un OR dentro de ese
parámetro, así que ?property_type=apartment&property_type=studio significa cualquiera de los dos tipos.
Los filtros de rango usan los prefijos min_ y max_ y son inclusivos.
Ordena con el nombre de un campo, con un signo menos delante para descendente: ?sort=-price.
El orden siempre desempata por id, así que la paginación es determinista incluso cuando muchas
fichas comparten precio. Los resultados de búsqueda se ordenan por relevancia e ignoran sort.
Campos parciales y expansión
Dos parámetros moldean el contenido en direcciones opuestas. fields reduce una
ficha a lo que has pedido, y expand incrusta un recurso relacionado que de otro modo sería
una llamada aparte. Juntos suelen colapsar un N+1 en una única
petición:
GET /v1/api/properties?fields=id,price,living_area&expand=imagesIdempotencia
Envía una Idempotency-Key en todo POST que cree algo. Una expiración de red
no te dice nada sobre si el servidor actuó, y reintentar sin una
clave es como aparecen los anuncios duplicados.
curl -sS -X POST "https://api.skautik.com/v1/api/properties" \
-H "Authorization: Bearer $SKAUTIK_API_KEY" \
-H "Idempotency-Key: 6f1c2a7e-4d90-4a1b-9f33-0c2f5b8e77aa" \
-H "Content-Type: application/json" \
-d @property.jsonRepetir una clave devuelve la respuesta original en lugar de crear una segunda
ficha. Reutilizar una con un cuerpo distinto es un error y devuelve 409. Las claves
se recuerdan durante 24 horas. Genera un UUID por creación lógica, no por
intento.
Peticiones condicionales
Las lecturas devuelven un ETag. Devuélvelo como If-None-Match y un recurso sin cambios
responde 304 sin cuerpo, lo que no te cuesta cuota.
En un PATCH, envía el ETag como If-Match. Si la ficha ha cambiado desde que la
leíste, la escritura se rechaza con 412 en lugar de descartar en silencio la
otra edición. Vuelve a leer, vuelve a aplicar, reintenta.
Formatos de datos
| Tipo | Formato |
|---|---|
| Marcas de tiempo | RFC 3339, siempre UTC, siempre con el sufijo Z. Nunca una hora local y nunca un entero de época. |
| Dinero | Unidades menores enteras con una moneda ISO 4217 aparte. 42900000 con EUR son 429.000,00. Nunca se usan decimales flotantes para el dinero. |
| Superficies | Metros cuadrados como número. No se aplica ninguna conversión; la ficha de mercado indica su propia convención de unidad. |
| Identificadores | Cadenas opacas con prefijo, como prop_ y whk_. No los parsees; el prefijo sirve para reconocerlos en los registros, no para enrutar. |
| Valores ausentes | Un null explícito, no una clave omitida ni una cadena vacía. Null significa que la fuente nunca lo proporcionó, que es distinto de cero. |
Identificadores de petición
Todas las respuestas llevan una cabecera X-Request-Id, repetida en el cuerpo de cualquier
error. Regístralo. Citar uno permite a soporte encontrar la petición exacta en lugar de
pedirte que reproduzcas el problema.