Configuración

Configura el cliente listingsapi-js: resolución de la clave de API, cambios de la URL base, tiempos de espera y reintentos automáticos.

Opciones del constructor

ListingsAPI acepta un único objeto de opciones, totalmente opcional:

OpciónTipoObligatoriaValor predeterminadoDescripción
apiKeystringNoprocess.env.LISTINGSAPI_KEYTu clave de Listings API. Si se omite, el cliente lee la variable de entorno LISTINGSAPI_KEY y lanza AuthenticationError si no se ha definido ninguna de las dos.
baseUrlstringNohttps://listingsapi.comPermite cambiar el host de la API, lo que resulta útil para proxies o entornos de preproducción. Las barras finales se eliminan automáticamente.
timeoutnumberNo240000Tiempo de espera máximo por solicitud en milisegundos, aplicado mediante AbortSignal.timeout.
maxRetriesnumberNo2Reintentos automáticos ante límites de frecuencia, errores del servidor y fallos de red. Solo se reintentan las lecturas; las escrituras nunca se reintentan. Establece el valor en 0 para desactivarlos.
TypeScript
import { ListingsAPI } from 'listingsapi-js'; const client = new ListingsAPI(); // reads LISTINGSAPI_KEY from env // Every default spelled out:const custom = new ListingsAPI({apiKey: process.env.LISTINGSAPI_KEY,baseUrl: 'https://listingsapi.com',timeout: 240000,   // 4 minutes per attemptmaxRetries: 2,     // up to 3 attempts total});

Obtención de la clave de API

Nunca incluyas la clave directamente en el código fuente. El constructor sin argumentos lee LISTINGSAPI_KEY del entorno:

Shell
export LISTINGSAPI_KEY="your-api-key"
TypeScript
const client = new ListingsAPI();

También puedes pasar una clave que hayas obtenido de un gestor de secretos:

TypeScript
import { getSecret } from './secrets.js'; const apiKey = await getSecret('LISTINGSAPI_KEY');const client = new ListingsAPI({ apiKey });

Si no se encuentra ninguna clave en ninguno de los dos lugares, el constructor lanza AuthenticationError de inmediato, antes de realizar cualquier solicitud.

Cambio de la URL base

Configura el cliente para que use un proxy interno o un entorno de preproducción:

TypeScript
const client = new ListingsAPI({baseUrl: 'https://listings-proxy.internal.example.com',});

Las barras finales se eliminan automáticamente, por lo que 'https://listingsapi.com/' y 'https://listingsapi.com' se comportan igual.

Tiempos de espera

Cada intento se ejecuta internamente con AbortSignal.timeout(timeout) (Node 18+), por lo que no necesitas añadir tu propio AbortController a las llamadas al SDK. El valor predeterminado es de 240000 ms (4 minutos) por intento.

Un intento que supera el tiempo de espera se considera un fallo de conexión: el cliente lo reintenta mientras queden intentos disponibles, y el fallo final lanza APIConnectionError. Reduce el tiempo de espera para las rutas de ejecución sensibles a la latencia:

TypeScript
const client = new ListingsAPI({ timeout: 15000 }); // 15 s per attempt

Reintentos automáticos

El cliente reintenta las solicitudes que reciben respuestas con los estados 429, 500, 502, 503 y 504, así como las que sufren fallos de red (errores de DNS, conexiones rechazadas, tiempos de espera agotados), solo para los métodos seguros: GET, HEAD y OPTIONS. A partir de 0.3.2, una escritura (POST, DELETE) se envía exactamente una vez y su fallo se comunica de inmediato. Con el valor predeterminado maxRetries: 2, cada lectura realiza hasta 3 intentos.

La API v4 no admite Idempotency-Key ni detecta escrituras repetidas, por lo que una escritura que supera el tiempo de espera o devuelve un 5xx puede haberse aplicado ya. Reintentarla sin comprobarlo crearía una segunda ubicación, publicación o respuesta a una reseña. Vuelve a leer el registro mediante una clave que controles antes de repetir una escritura.

La espera antes de cada reintento:

  1. Si la respuesta incluye una cabecera Retry-After con un número positivo de segundos, el cliente espera exactamente ese tiempo.
  2. De lo contrario, el tiempo de espera aumenta de forma exponencial: 500 ms antes del primer reintento y el doble en cada reintento posterior (1 s, 2 s y así sucesivamente).

Los fallos de red se reintentan de inmediato, sin espera. Cuando se agotan los intentos, la última respuesta se convierte en un error con un tipo específico (RateLimitError, InternalServerError y otros; consulta Gestión de errores), y un fallo de red que agota los intentos lanza APIConnectionError.

TypeScript
// Fail fast and own the retry policy yourself:const client = new ListingsAPI({ maxRetries: 0 });

ID de ubicación

En cualquier punto donde el SDK acepte un ID de ubicación, los ID numéricos se codifican automáticamente en el formato base64 de la API (Location:<id>), y los ID ya codificados se pasan sin cambios. La función auxiliar se exporta por si necesitas obtener el formato codificado:

TypeScript
import { encodeLocationId } from 'listingsapi-js'; encodeLocationId(16808);                  // 'TG9jYXRpb246MTY4MDg='encodeLocationId('TG9jYXRpb246MTY4MDg='); // returned as-is

Formato de las cabeceras

Cada solicitud se autentica con:

Code
Authorization: API <your-key>Content-Type: application/json

El SDK establece estas cabeceras automáticamente en cada llamada. No necesitas configurarlas.

Configuración de un proyecto TypeScript

El SDK está diseñado para TypeScript e incluye los tipos, por lo que no necesitas instalar un paquete @types aparte. Fija la versión para obtener compilaciones reproducibles:

Shell
npm install listingsapi-js@0.3.2

Un tsconfig.json mínimo para un proyecto con Node 18+:

tsconfig.json
{"compilerOptions": {  "target": "ES2022",  "module": "Node16",  "moduleResolution": "Node16",  "strict": true,  "outDir": "dist"}}

Para proyectos ESM con "type": "module" en package.json, usa "module": "Node16" y "moduleResolution": "Node16". Para proyectos CJS, "module": "CommonJS" y "moduleResolution": "Node" funcionan correctamente; el paquete incluye ambas compilaciones, y el código CommonJS lo carga con const { ListingsAPI } = require('listingsapi-js').

Uso sin TypeScript

listingsapi-js se compila a JavaScript sin dependencias en tiempo de ejecución. Puedes importarlo desde un archivo .js o .mjs sin un paso de compilación:

script.mjs
import { ListingsAPI } from 'listingsapi-js'; const client = new ListingsAPI();const page = await client.fetchAllLocations({ first: 5 });for (const location of page.locations) {console.log(location.name, location.city); // Acme Dental Midtown}

Próximos pasos