usestrix/strix · error · SpecParseError

Postman API returned HTTP {response.status_code} for {label}

Error message

Postman API returned HTTP {response.status_code} for {label}.

What it means

Catch-all SpecParseError for any Postman API response status other than 200/401/404 — typically 403 (permissions/plan limits), 429 (rate limit), or 5xx. The status code and resource label are included in the message.

Source

Thrown at strix/utils/api_spec.py:265

            "fetch from the Postman API, or pass a local collection file instead.",
        )
    try:
        response = requests.get(
            url,
            headers={"X-Api-Key": api_key, "Accept": "application/json"},
            timeout=_POSTMAN_FETCH_TIMEOUT,
        )
    except requests.RequestException as exc:
        raise SpecParseError(f"Failed to reach the Postman API: {exc}") from exc

    if response.status_code == 401:
        raise SpecParseError("Postman API rejected the key (401). Check POSTMAN_API_KEY.")
    if response.status_code == 404:
        raise SpecParseError(
            f"Postman {label} not found (404). Check the id and that the key can access it.",
        )
    if response.status_code != 200:
        raise SpecParseError(f"Postman API returned HTTP {response.status_code} for {label}.")
    try:
        payload = response.json()
    except ValueError as exc:
        raise SpecParseError(f"Postman API returned non-JSON for {label}") from exc
    if not isinstance(payload, dict):
        raise SpecParseError(f"Unexpected Postman API response shape for {label}")
    return payload


def fetch_postman_collection(collection_uid: str, api_key: str) -> dict[str, Any]:
    """Fetch a collection from the Postman API and return the raw collection dict.

    Uses ``GET /collections/{uid}`` with the ``X-Api-Key`` header. The endpoint
    wraps the collection under a ``collection`` key, unwrapped here so the result
    matches an exported collection file.
    """
    payload = _postman_api_json(
        f"{POSTMAN_API_BASE}/collections/{collection_uid}",

View on GitHub (pinned to 8551339130)

Solutions

  1. For 429: wait (check Retry-After) and retry once, and serialize CI jobs that share the key
  2. For 403: verify the key's scope/plan permits collection API reads
  3. For 5xx: check status.getpostman.com, then retry; or export the collection locally to remove the dependency

Example fix

# before: parallel CI jobs share one key -> 429

# after: fetch once, cache the artifact
curl -H "X-Api-Key: $POSTMAN_API_KEY" .../collections/$UID > postman-cache.json  # CI cache step
strix --api-spec ./postman-cache.json
Defensive patterns

Strategy: retry

Validate before calling

def within_rate_limit() -> bool:
    # simple local guard; Postman does not expose headers pre-call
    return (time.time() - last_call_ts) >= min_interval_seconds

Try / catch

except SpecParseError as e:
    m = re.search(r"HTTP (\d+)", str(e))
    code = int(m.group(1)) if m else 0
    if code == 429:
        wait on Retry-Then backoff and retry once
    elif code >= 500:
        retry once after a short delay
    else:
        surface the error (permissions/plan) — retrying will not help

Prevention

When it happens

Trigger: Hammering the API past the rate limit (429); a free-plan key hitting an endpoint it cannot use (403); Postman-side incident (500/503).

Common situations: Retries in a tight loop after a transient failure; shared CI key exhausted by parallel jobs; plan restrictions on API access.

Related errors


AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15). Data as JSON: /api/errors/8aed724e80bd2c80. Report an issue: GitHub.