Enlazar una marca completa

Obtén un link para cada producto de una marca y mantenlos al día con una ejecución cada noche. Son unas 40 solicitudes para una marca de 2.000 productos.

1. Busca la marca

Terminal
curl "https://api.stilo.io/v1/brands?q=nars" \
  -H "Authorization: Bearer $STILO_API_KEY"

El id de cada marca es su slug, por ejemplo nars.

2. Lista sus productos, de 100 en 100

Terminal
curl "https://api.stilo.io/v1/products?brand=nars&limit=100" \
  -H "Authorization: Bearer $STILO_API_KEY"

Sigue pidiendo con cursor=<next_cursor> hasta que next_cursor sea null. Cada producto ya indica si tienes un link (link) y cuánto ganas (commission; null significa que no hay comisión).

3. Crea los links en lotes

Terminal
curl https://api.stilo.io/v1/links/batch \
  -H "Authorization: Bearer $STILO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"items": [{"product_id": "prd_..."}, {"product_id": "prd_..."}]}'

Hasta 100 elementos por llamada. Cada resultado dice created, existing o error, en el mismo orden en que los enviaste.

4. Córrelo cada noche

Como hay un solo link por producto, correr el mismo script otra vez devuelve los mismos links, nunca duplicados. Para traer solo lo que cambió, envía updated_since con la hora de tu última ejecución:

Terminal
curl "https://api.stilo.io/v1/products?brand=nars&updated_since=2026-11-04T03:00:00Z&limit=100" \
  -H "Authorization: Bearer $STILO_API_KEY"
Un producto que ya no aparece en la lista se retiró o se agotó. Su link sigue funcionando; si quieres, ocúltalo en tu sitio.

Ejemplo completo (Python)

sync_brand.py
import os
import requests

API = "https://api.stilo.io/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['STILO_API_KEY']}"}


def products(brand, updated_since=None):
    params = {"brand": brand, "limit": 100}
    if updated_since:
        params["updated_since"] = updated_since
    while True:
        page = requests.get(f"{API}/products", headers=HEADERS, params=params, timeout=30).json()
        yield from page["data"]
        if not page["next_cursor"]:
            return
        params["cursor"] = page["next_cursor"]


def sync(brand, updated_since=None):
    todo = [p for p in products(brand, updated_since) if p["commission"] and not p["link"]]
    links = {}
    for start in range(0, len(todo), 100):
        chunk = todo[start:start + 100]
        body = {"items": [{"product_id": p["id"]} for p in chunk]}
        result = requests.post(f"{API}/links/batch", headers=HEADERS, json=body, timeout=60).json()
        for product, item in zip(chunk, result["data"]):
            if item["link"]:
                links[product["id"]] = item["link"]["short_url"]
            else:
                print("skipped", product["name"], item["error"]["type"])
    return links


if __name__ == "__main__":
    for product_id, url in sync("nars").items():
        print(product_id, url)

Consejos

  • Respeta Retry-After cuando recibas un 429; los límites son generosos, así que un script normal rara vez llega a ellos.
  • Un link a la tienda completa se pide con {"retailer_id": "ret_..."}.
  • Para fijar un link a una variante (un color, una talla), envía variant_id junto con product_id, o pega una URL de la tienda que ya indique la variante.