Skip to content

Guides

Nightly ERP sync

Copy every comparison set into your ERP once a day. Page through all sets 100 at a time and follow next_cursor until it's null. A catalogue of 3,000 sets takes 30 requests.

This script writes one row per competitor price to prices.csv, and retries the way Rate limits recommends.

Python
import csv
import os
import time

import requests

API = "https://api.getprice.ai/v1"
# Retry these. Never retry 500: it won't fix itself.
RETRYABLE = {429, 502, 503, 504}
KEY = os.environ["GETPRICE_API_KEY"]

session = requests.Session()
session.headers["Authorization"] = f"Bearer {KEY}"


def get_with_retry(url, params, attempts=6):
    """GET, waiting out 429/503 and network errors."""
    for attempt in range(attempts):
        backoff = min(2**attempt, 60)
        try:
            resp = session.get(
                url, params=params, timeout=60
            )
        except requests.RequestException:
            time.sleep(backoff)
            continue
        if resp.status_code in RETRYABLE:
            wait = resp.headers.get("Retry-After")
            time.sleep(int(wait or backoff))
            continue
        if resp.status_code >= 400:
            p = resp.json()
            raise RuntimeError(
                f"{p['code']}: {p['detail']}"
                f" ({p['request_id']})"
            )
        return resp.json()
    raise RuntimeError(f"Gave up on {url}")


def comparison_sets():
    params = {"limit": 100}
    while True:
        page = get_with_retry(
            f"{API}/comparison-sets", params
        )
        yield from page["data"]
        if page["next_cursor"] is None:
            return
        params["cursor"] = page["next_cursor"]


COLUMNS = [
    "sku", "set_id", "competitor", "amount",
    "currency", "last_collected_at", "stale", "review",
]
sets = rows = 0
with open("prices.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(COLUMNS)
    for cset in comparison_sets():
        sets += 1
        for e in cset["competitors"]:
            price = e["price"] or {}
            writer.writerow([
                cset["sku"],
                cset["id"],
                e["competitor"]["name"],
                price.get("amount"),
                price.get("currency"),
                e["last_collected_at"],
                e["stale"],
                e["match"]["review"],
            ])
            rows += 1
print(f"Sets: {sets}. Competitor rows: {rows}.")
Output
Sets: 2. Competitor rows: 4.

Make the sync reliable#

  • Replace, don't append. For each set, replace the rows you stored last time. A competitor removed from a set then disappears from your ERP too.
  • Keep the filters identical on every page. After the first page, change only cursor and limit.
  • Run the sync after collection. Competitor prices are collected early in the morning, South African time, on your refresh days. A sync at about 10:00 SAST picks up that morning's run.
  • A set's updated_at changes when its contents change, not on every price read. Don't use it to decide whether to re-read prices.